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

接下來,我們逐一簡單介紹一下。
存儲引擎詳解
插件式的存儲引擎設計是 MySQL 區別於其他數據庫的一個重要特性,MySQL 的核心在於存儲引擎。

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

這里設表一共有三列,假設我們以 Col1為主鍵,則上圖是一個 MyISAM 表的主索引(Primary key)示意。可以看出 MyISAM 的索引文件僅僅保存數據記錄的地址。
在 MyISAM 中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。
如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

同樣也是一顆 B+Tree,data 域保存數據記錄的地址。因此,MyISAM 中索引檢索的算法為首先按照 B+Tree 搜索算法搜索索引,如果指定的 Key 存在,則取出其 data 域的值,然后以data域的值為地址,讀取相應數據記錄。
MyISAM 索引方式叫做「“非聚集”」的,這是為了與 InnoDB 的聚集索引區分。
InnoDB 索引原理
雖然 InnoDB 也使用 B+Tree 作為索引結構,但具體實現方式卻與 MyISAM 截然不同。
-
第一個重大區別是 InnoDB 的數據文件本身就是索引文件。
從 上文知道,MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。
而在InnoDB中,表數據文件本身就是按 B+Tree 組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的 key 是數據表的主鍵,因此 InnoDB 表數據文件本身就是主索引。

上圖是 InnoDB 主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做「聚集索引」。
因為 InnoDB 的數據文件本身要按主鍵聚集,所以 InnoDB 要求表必須有主鍵(MyISAM 可以沒有),如果沒有顯式指定,則MySQL 系統會自動選擇一個可以唯一標識數據記錄的列作為主鍵,如果不存在這種列,則 MySQL 自動為 InnoDB 表生成一個隱含字段作為主鍵,這個字段長度為 6 個字節,類型為長整形。
-
第二個與 MyISAM 索引的不同是 InnoDB 的輔助索引 data 域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。
例如,下圖為定義在Col3上的一個輔助索引:

這里以英文字符的ASCII碼作為比較准則。
聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。
對於我們開發而言,了解不同存儲引擎的索引實現方式對於正確使用和優化索引都非常有幫助。
例如知道了InnoDB的索引實現后,就容易明白為什么不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。
例如用非單調的字段作為主鍵在 InnoDB 中不是個好主意,因為 InnoDB 數據文件本身是一顆 B+Tree,非單調的主鍵會造成在插入新記錄時數據文件為了維持 B+Tree 的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。
