什麼是表引擎
我們看到的表結構,它的本質是數據在硬盤中的存儲。根據不同的特性,數據的存儲方式不同。比如:對於每一條數據,在硬盤中它是怎麼存儲的,怎麼壓縮的,怎麼建立索引和優化的,它的讀取和寫入是怎麼實現的。這些完整的一條路徑,我們稱之爲表引擎。
選擇的依據
選擇的依據,是我們的需求,我們的需求很大程度上決定我們的選擇。有的時候,我們的習慣決策着這個過程。這裏,我們關注一下方面:
併發性,同一時間支持的寫入和讀取特性;
安全性,物理存儲結構,異常發生時數據的是否可靠;
事務性,數據執行的顆粒,以及提供的定義原子操作的特性;
查詢優化,這裏我們指查詢緩存和索引;
在開發上,我們主要關注:(1,3,4),在運維層面,我們關注(2)。
在表的選擇上,最常用的是如下:
MyIsam
Innodb
Memory(Heap)
從案例開始
現在我們要做一個留言板,我們發現這個留言板可能有幾種情況:
有很多人同時留言,同時,查看留言的人也很多;
留言的人很少,每天查看留言的人非常多;
我們的功能有留言獎勵,每天前10個留言的,會有積分獎勵;
我們的留言板有點像實時聊天器,對性能要求和實時性要求非常高;
MYSIAM
在5.0的時代,這個表是使用得非常普遍的,我瞭解的Discuz就是使用這種表。它的優勢:查詢速度,被很多人看重。我們看看它的一些特點:
理論上存儲無限制(與操作系統的文件系統有關)
存在text/blob全文索引
索引緩存
數據壓縮
低存儲空間和低內存佔用
高速寫入
查詢緩存
串行寫入時,全表鎖(讀和寫)
不支持事務
集羣支持
B-Tree索引
create table a_myisam (.....) ENGINE = MYISAM;
以上特性,我們看到MyIsam主要是爲查詢而設計的,也是最初大家做數據存儲時考慮的東西。
InnoDB 從5.1開始,InnoDB慢慢發展起來,並且成爲重要數據的存儲引擎。它的特點如下:
有限制的存儲
索引緩存
支持事務
查詢緩存
寫入行鎖
B-Tree索引
create table a_myisam (.....) ENGINE = InnoDB;
InnoDB更加穩定和成熟,也爲更多需求提供解決方案。
Memory
查詢速度快
mysql重啓後丟失
B-Tree和HASH索引
僅僅是爲了快,小量數據。
A:很多人同時留言,看留言的人也很多
這意味着什麼?我們的寫入速度要夠快且寫入不影響讀取。或者,我們可以並行寫入。這種情況,如果我們選擇MyIsam,寫入量的增加會導致全表上鎖,以至於讀取時,要等待鎖的釋放;那麼,顯然,MyIsam會造成表性能瓶頸。這種情況,我們選擇Innodb。理由如下:
Innodb寫入時,鎖爲行鎖;不影響其它寫入,影響少量讀(有可能大量);
Innodb的查詢性能理論上比Myisam稍差,但是非常小,可忽略;
B:留言的人很少,每天查看留言的人非常多
這個時候,選擇MyIsam,沒有什麼問題。(讀/寫比較高)
C:我們的功能有留言獎勵,每天前10個留言的,會有積分獎勵
我們需要一些原子級別的操作,也就是在判斷某條留言是前10名的時候,就將它標記,而這個標記需要原子級的:標記的過程中不允許別人查詢和寫入(全表鎖)。這是什麼意思?由於我們的操作是沒有嚴格的前後順序的,計算機的CPU運算分片本質是串行的。假設這個時候你有兩條命令:
查詢是否前10個
增加積分
假設現在已經有9個條留言了,那麼這個時候來了兩個請求,都查詢自己是否是前10個。第一個用戶查到自己是第10個,然後在它要執行第二步的時候,第11個用戶來了,他也查詢自己是第10個,如果沒有保護機制,那麼第11個也被認爲是滿足條件,他也會被加分。
如何實現?
一般情況下我們會增加一個字段來做標記,這個字段假設爲:lock,那麼更新的時候保證這個中間是沒有其它操作的。我們稱之爲事務。
start
select ... from table where lock = 0 for update;
update table set lock = 1;
commit
D:我們的留言板有點像實時聊天器,對性能要求和實時性要求非常高
呵呵,這個不用說了,使用innodb和memory都可以。一般我們使用內存存儲,會把它當做K-V來使用,根據設計的情況來選擇。(不過,業內很少時候,內存的存儲一般都會選擇Memcache和Redis)。
總結一下
如果讀/寫 比很大的話,假設這個尺度爲10,那麼,就使用myisam(寫入併發小的情況)
如果需要事務的支持,使用innodb
如果需要對併發性(寫入)有要求的話,使用innodb
其它情況,可以根據實際場景選擇
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。互聯網+時代,時刻要保持學習,攜手千鋒PHP,Dream It Possible。