資料庫表設計之儲存引擎

Yin發表於2021-06-28

儲存引擎的選擇

不同的儲存引擎都有各自的特點,從而適應不同的需求,如下表所示:

image

接下來,我們逐一簡單介紹一下。

儲存引擎詳解

外掛式的儲存引擎設計是 MySQL 區別於其他資料庫的一個重要特性,MySQL 的核心在於儲存引擎。

image

儲存引擎索引原理對比

MyISAM 索引原理

MyISAM 引擎使用B+Tree作為索引結構,葉節點的 data 域存放的是「資料記錄的地址」。下圖是MyISAM索引的原理圖:

image

這裡設表一共有三列,假設我們以 Col1為主鍵,則上圖是一個 MyISAM 表的主索引(Primary key)示意。可以看出 MyISAM 的索引檔案僅僅儲存資料記錄的地址

在 MyISAM 中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複

如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

image

同樣也是一顆 B+Tree,data 域儲存資料記錄的地址。因此,MyISAM 中索引檢索的演算法為首先按照 B+Tree 搜尋演算法搜尋索引,如果指定的 Key 存在,則取出其 data 域的值,然後以data域的值為地址,讀取相應資料記錄。

MyISAM 索引方式叫做「“非聚集”」的,這是為了與 InnoDB 的聚集索引區分。

InnoDB 索引原理

雖然 InnoDB 也使用 B+Tree 作為索引結構,但具體實現方式卻與 MyISAM 截然不同。

  • 第一個重大區別是 InnoDB 的資料檔案本身就是索引檔案

    從 上文知道,MyISAM索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的地址。

    而在InnoDB中,表資料檔案本身就是按 B+Tree 組織的一個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄。這個索引的 key 是資料表的主鍵,因此 InnoDB 表資料檔案本身就是主索引。

image

​ 上圖是 InnoDB 主索引(同時也是資料檔案)的示意圖,可以看到葉節點包含了完整的資料記錄。這種索引叫做「聚集索引」

​ 因為 InnoDB 的資料檔案本身要按主鍵聚集,所以 InnoDB 要求表必須有主鍵(MyISAM 可以沒有),如果沒有顯式指定,則MySQL 系統會自動選擇一個可以唯一標識資料記錄的列作為主鍵,如果不存在這種列,則 MySQL 自動為 InnoDB 表生成一個隱含欄位作為主鍵,這個欄位長度為 6 個位元組,型別為長整形。

  • 第二個與 MyISAM 索引的不同是 InnoDB 的輔助索引 data 域儲存相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。

    例如,下圖為定義在Col3上的一個輔助索引:

image

這裡以英文字元的ASCII碼作為比較準則。

聚集索引這種實現方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄

對於我們開發而言,瞭解不同儲存引擎的索引實現方式對於正確使用和優化索引都非常有幫助。

例如知道了InnoDB的索引實現後,就容易明白為什麼不建議使用過長的欄位作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。

例如用非單調的欄位作為主鍵在 InnoDB 中不是個好主意,因為 InnoDB 資料檔案本身是一顆 B+Tree,非單調的主鍵會造成在插入新記錄時資料檔案為了維持 B+Tree 的特性而頻繁的分裂調整,十分低效,而使用自增欄位作為主鍵則是一個很好的選擇。


END

相關文章