對於MySQL存儲引擎、索引類型的選擇可能大多數時候無腦選InnoDB就行了,但是理論上存儲引擎的選擇應該綜合考量事務安全、併發量、支持的索引類型等因素。
同樣對於索引類型的選擇雖然大多數情況下選B樹索引就完事了,但是B樹索引並非在任何情況下都是最優的,某些業務場景下可能選全文索引或者哈希索引更加合適。這也是面試中經常問到的基礎題。
本文主要內容是參考了MySQL官方文檔和其他網站內容結合自己的理解總結而成,希望能幫到大家,如果覺得有收穫記得關注哦!
1.1. <strong>MySQL存儲引擎
1.1.1. <strong>存儲引擎特性
參考鏈接:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
下面以MySQL5.7為準,列舉了4個主要存儲引擎的特性對比(對MySQL官方文檔進行了順序調整和刪減):
![MySQL存儲引擎如何選擇,索引如何選擇,索引的數據結構?](http://p2.ttnews.xyz/loading.gif)
備註: MySQL5.6+ InnoDB支持全文索引。
1.1.2. <strong>存儲引擎應用場景
參考鏈接:
https://mp.weixin.qq.com/s/Yjh_fPgrjuhhOZyVtRQ-SA
https://blog.csdn.net/zhangyuan19880606/article/details/51217952
MySQL 5.5+的默認存儲引擎為InnoDB, 之前為MyISAM。
InnoDB和MyISAM默認的索引都是B樹索引,Memory默認的索引是哈希索引。
InnoDB支持事務,支持行級鎖,支持數據緩存,支持聚集索引,適用於大部分併發量大、數據量大的業務系統。
MyISAM擁有較高的插入、查詢速度,但不支持事物,適用於數據倉庫等場景。
MEMORY將表中的數據存儲到內存中,且支持哈希索引,因此精確查詢的速度較快,適用於數據量較小、對查詢速度要求較高的場景。
Archive插入較快,適合存儲歸檔數據,如日誌信息。
2. <strong>索引
2.1. <strong>索引原理
2.1.1. <strong>索引基礎
參考鏈接:https://tech.meituan.com/mysql_index.html
圖書館為了提高查找書籍的效率需要為書籍建立索引,數據庫為了提高數據的查詢效率也需要為數據建立索引。但數據庫索引要複雜許多,因為不僅要考慮等值查詢,還有多條件查詢(and)、範圍查詢(>、
一般訪問磁盤的成本大概是訪問內存的十萬倍左右。
一般文件系統為了提高磁盤訪問效率,當一次IO時,會把相鄰的數據也都讀取到內存緩衝區內(局部預讀性原理告訴我們,當計算機訪問一個地址的數據的時候,與其相鄰的數據也大概率會被訪問到),然後再進行查找。
2.2. <strong>索引數據結構
2.2.1. <strong>B+樹索引
參考文獻:《MySQL技術內幕-InnoDB存儲引擎第2版》
B+樹(binary plus tree)是從平衡二叉樹(左子樹的鍵值小於根節點的鍵值,右子樹的鍵值大於根節點的鍵值)演化而來,但B+樹並不是二叉樹。B+樹被廣泛應用於文件系統、數據庫中建立索引。
B+樹的簡單定義:B+樹是為磁盤或其他存儲設備設計的一種平衡查找樹。B+樹中所有記錄都是按鍵值大小順序存放在葉子節點上,各葉子節點通過指針進行連接。
數據庫中B+樹的高度一般為2~4。InnoDB中B樹索引頁大小為16KB。
通過B樹索引查找數據時的IO次數取決於b+樹的高度h,假設當前數據表的數據為N,每個磁盤塊的數據項的數量是m,則有h=log (m+1)N。即B+樹的高度取決於表的數據量和磁盤塊的大小。
B+樹的數據結構示意圖如下(其中P代表指針):
![MySQL存儲引擎如何選擇,索引如何選擇,索引的數據結構?](http://p2.ttnews.xyz/loading.gif)
2.2.2. <strong>哈希索引
哈希索引(Hash indexes)採用哈希表來對鍵值進行查找,時間複雜度為O(1)。
使用哈希索引時對於鍵值的等值查詢是非常快的,但是其他類型的查詢如範圍查詢、模糊查詢、排序等是不能使用哈希索引的。這是哈希索引使用比較少的主要原因。
2.2.3. <strong>全文索引
對於 select * from blog where content like '%java%'是無法使用B樹索引的。在電商網站中如果要對商品的明細進行關鍵字查詢,則需要使用全文索引。
全文索引查找條件使用 MATCH AGAINST。
全文索引(Full-text search indexes)使用倒排索引(inverted index)實現。倒排索引會記錄文本中的每個關鍵字出現在文檔中的位置。
2.3. <strong>索引分類
參考鏈接:
https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html
https://www.2cto.com/kf/201602/490519.html
2.3.1. <strong>聚集索引
聚集索引(Clustered Index)又稱聚簇索引,其葉子節點存放記錄。
每個InnoDB 表有一個特定的索引叫做聚集索引,存儲行的數據。
如果你的表定義了主鍵那麼主鍵就是聚集索引,如果沒有定義主鍵,MySQL 會選擇第一個非空唯一索引列作為聚集索引,如果表中也沒有唯一索引,InnoDB會生成一個類似RowId的隱藏的聚集索引。
2.3.2. <strong>二級索引
二級索引(secondary indexes)又稱輔助索引、非聚簇索引,其葉子節點存放索引值及指向主鍵的指針。
除聚集索引以外的索引,統稱為二級索引,如唯一索引、普通索引、組合索引等。
閱讀更多 高級JAVA指南 的文章