BTree特性
BTree又叫多路平衡查找樹,一顆m叉的BTree特性以下:mysql
- 樹中每一個節點最多包含m個孩子。
- 除根節點與葉子節點外,每一個節點至少有[ceil(m/2)]個孩子。
- 若根節點不是葉子節點,則至少有兩個孩子。
- 全部的葉子節點都在同一層。
- 每一個非葉子節點由n個key與n+1個指針組成,其中[ceil(m/2)-1] <= n <= m-1 。
BTree插入
以5叉BTree爲例,key的數量:公式推導[ceil(m/2)-1] <= n <= m-1。因此 2 <= n <=4。當n>4時,中間節點分裂到父節點,兩邊節點分裂。sql
- 以插入C N G A H E K Q M F W L T Z D P R X Y S爲例,前4個字母沒什麼好說的。
![](http://static.javashuo.com/static/loading.gif)
- 插入H,n>4,中間元素G字母向上分裂到新的節點。
- 插入E,K,Q不須要分裂。
- 插入M,中間元素M字母向上分裂到父節點G。
- 插入F,W,L,T不須要分裂。
- 插入Z,中間元素T向上分裂到父節點中。
- 插入D,中間元素D向上分裂到父節點中。而後插入P,R,X,Y不須要分裂。
- 最後插入S,NPQR節點n>5,中間節點Q向上分裂,但分裂後父節點DGMT的n>5,中間節點M向上分裂。須要注意的是,原BTree第三個子節點HKL會包含DG節點中。
到此,一個BTree的構建就完成了,怎麼樣?是否是很簡單。刪除操做比插入略微複雜,鑑於篇幅,不作敘述。數據結構
B+Tree
B+Tree爲BTree的變種,B+Tree與BTree的區別爲:性能
- 有n棵子樹的B+Tree最多含有n個key,而BTree最多含有n-1個key。
- B+Tree的葉節點保存全部的key信息,依key大小順序排列。
- 全部的非葉子節點均可以看做是key的索引部分,節點中只含有其子節點的最大(或最小)key。
![](http://static.javashuo.com/static/loading.gif)
因爲B+Tree只有葉子節點保存key信息,查詢任何key都要從root走到葉子。因此B+Tree的查詢效率更加穩定。優化
帶有順序指針的B+Tree
MySql索引數據結構對經典的B+Tree進行了優化。spa
在原B+Tree的基礎上,增長一個指向相鄰葉子節點的指針,就造成了帶有順序指針的B+Tree,提升區間訪問的性能。
如上圖訪問18-49的元素,只須要順着18的指針走向49便可。3d
MySql索引數據結構
在mysql中,索引的實現方式與存儲引擎相關,MySql支持多種索引類型,如B+Tree、Hash索引、全文索引等等。在此只關注MyISAM與InnoDB的B+Tree索引數據結構。指針
MyISAM的B+Tree索引
MyISAM的主鍵索引與輔助索引在結構上沒有任何區別,只是主鍵索引要求key惟一。能夠看出,MyISAM的索引葉節點保存的是表的行的物理地址值。
MyISAM的索引是「非彙集」的,這麼稱呼只是爲了與InnoDB的彙集索引相區分。blog
InnoDB的B+Tree索引
InnoDB的索引實現方式與MyISAM大相徑庭,InnoDB的B+Tree葉子節點保存有完整的記錄信息。這也解釋了上篇所說的InnoDB的索引與數據文件是同一個文件。索引
上圖是B+tree的主鍵索引,這種索引也叫作彙集索引。InnoDB索引必須按照主鍵彙集,全部InnoDB必需要包含有主鍵。若是沒有顯示指定,MySql會自動選擇一個惟一標識列或生成一個隱含字段做爲主鍵。
![](http://static.javashuo.com/static/loading.gif)
上圖是InnoDB的B+Tree輔助索引,B+Tree的葉子節點只保存主鍵的值而不是行的地址值。因此輔助索引的檢索須要檢索兩遍索引。
所以,對於InnoDB的B+Tree索引使用有兩個注意點:
- 建議使用主鍵自增。因爲B+Tree的特性,非自增的主鍵在插入時會形成B+Tree頻繁的分裂。
- 不建議主鍵字段過長。因爲全部的輔助索引都會檢索主鍵索引,過長的主鍵索引會使輔助索引過大。