數據庫設計之選擇合適的表引擎

什麼是表引擎
咱們看到的表結構,它的本質是數據在硬盤中的存儲。根據不一樣的特性,數據的存儲方式不一樣。好比:對於每一條數據,在硬盤中它是怎麼存儲的,怎麼壓縮的,怎麼創建索引和優化的,它的讀取和寫入是怎麼實現的。這些完整的一條路徑,咱們稱之爲表引擎。
選擇的依據
選擇的依據,是咱們的需求,咱們的需求很大程度上決定咱們的選擇。有的時候,咱們的習慣決策着這個過程。這裏,咱們關注一下方面:
mysql



  • 併發性,同一時間支持的寫入和讀取特性;sql

  • 安全性,物理存儲結構,異常發生時數據的是否可靠;緩存

  • 事務性,數據執行的顆粒,以及提供的定義原子操做的特性;安全

  • 查詢優化,這裏咱們指查詢緩存和索引;
    服務器

在開發上,咱們主要關注:(1,3,4),在運維層面,咱們關注(2)。
在表的選擇上,最經常使用的是以下:
併發



  • MyIsam運維

  • Innodb性能

  • Memory(Heap)
    優化

從案例開始
如今咱們要作一個留言板,咱們發現這個留言板可能有幾種狀況:
spa



  • 有不少人同時留言,同時,查看留言的人也不少;

  • 留言的人不多,天天查看留言的人很是多;

  • 咱們的功能有留言獎勵,天天前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

  • 其它狀況,能夠根據實際場景選擇

問答



  • 主從庫可使用不一樣的引擎麼?
    答:這個我沒有作過,還不瞭解;你們能夠本身查一下(mysql手冊)

  • 我想多問一點,使用memory或者Memcache和Redis,是否是相比myisam或innodb引擎對服務器內存的要求或佔用高不少?答:對的,有專門的內存服務器來幹這件事;

相關文章
相關標籤/搜索