B-樹性質mysql
B-樹能夠看做是對2-3查找樹的一種擴展,即他容許每一個節點有M-1個子節點。sql
1根節點至少有兩個子節點數據庫
2每一個節點有M-1個key,而且以升序排列併發
3位於M-1和M key的子節點的值位於M-1 和M key對應的Value之間性能
其它節點至少有M/2個子節點spa
下圖是一個M=3 階的B樹3d
這裏簡單說明下指針
圖中的小黑方塊表示對應關鍵字所表明的文件的存儲位置,實際上能夠看作是一個地址,好比根節點中17旁邊的小黑塊表示的就是關鍵字17所對應的文件在硬盤中的存儲地址。blog
P是指針,排序
須要注意的是:指針(P),關鍵字(17),以及關鍵字所表明的文件地址這三樣東西合起來構成了B樹的一個節點,這個節點存儲在一個磁盤塊上
查找過程
下面,看看搜索關鍵字的29的文件的過程:
從根節點開始,讀取根節點信息,根節點有2個關鍵字:17和35。由於17 < 29 < 35,因此找到指針P2指向的子樹,也就是磁盤塊3(第1次I/0操做)
讀取當前節點信息,當前節點有2個關鍵字:26和30。26 < 29 < 30,找到指針P2指向的子樹,也就是磁盤塊8(第2次I/0操做)
讀取當前節點信息,當前節點有2個關鍵字:28和29。比較找到了!(第3次I/0操做)
B+樹性質
B+樹是對B樹的一種變形樹,它與B樹的差別在於:
非葉子結點的子樹指針與關鍵字個數相同
非葉結點僅具備索引做用,跟記錄有關的信息均存放在葉結點中。
全部分支節點的關鍵字都是對應子樹中關鍵字的最大值(或最小值)
樹的全部葉結點構成一個有序鏈表,能夠按照關鍵碼排序的次序遍歷所有記錄。
查找過程與b樹相似,這裏就再也不描述了。
爲何mysql數據庫採用b+樹而不是b樹?
B樹在提升了IO性能的同時並無解決遍歷元素的效率比較低的問題,
而因爲b+樹的特色,只須要去遍歷葉子節點就能夠實現整棵樹的遍歷.
並且在實際開發中,基於範圍的查詢是很是頻繁的,
而B樹不支持這樣的操做(或者說效率過低)
關於B樹和B+樹相關應用拓展
B樹通常用於數據庫索引或者文件系統,這裏咱們討論mysql的兩種不一樣 引擎
Myisam Innodb
1 MyISAM
MyISAM中有兩種索引,分別是主索引和輔助索引, 他們的數據都是那列的指針
在這裏面的主索引使用主鍵進行建立,
而二級(輔助)索引中鍵值則是其餘索引列。
MyISAM分別會存一個索引文件和數據文件。它的主索引是非彙集索引。
當咱們查詢的時候咱們找到葉子節點中保存的地址,而後經過地址咱們找到所對應的信息
Innodb
InnoDB索引和MyISAM最大的區別是它只有一個數據文件,而且在輔助索引中不存儲那列的指針,而是存儲主鍵。
在InnoDB中,表數據文件自己就是按B+Tree組織的一個索引結構,
這棵樹的葉子節點數據域保存了完整的數據記錄。
咱們把它的主索引叫作彙集索引。
而它的輔助索引和MyISAM也會有所不一樣,它的輔助索引都是將主鍵做爲數據域。而它的輔助索引和MyISAM也會有所不一樣,它的輔助索引都是將主鍵做爲數據域。
由於MySQL重建聚簇索引,重建完後,原數據全部的page都發生了變更,這個時候你必定但願非聚簇索引記錄的都是PK,而非page指針了
(因爲每一個輔助索引都包含主鍵索引,所以,爲了減少輔助索引所佔空間,咱們一般但願 InnoDB 表中的主鍵索引儘可能定義得小一些)
當咱們查找的時候經過輔助索引要先找到主鍵,而後經過主索引再找到對於的主鍵,獲得信息。
注意一下兩點:
1彙集索引的數據的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的數據必定也是相鄰地存放在磁盤上的。聚簇索引要比非聚簇索引查詢效率高不少。
例如,若是應用程序執行的一個查詢常常檢索某一日期範圍內的記錄,則使用匯集索引能夠迅速找到包含開始日期的行,而後檢索表中全部相鄰的行,直到到達結束日期。這樣有助於提升此類查詢的性能
2彙集索引這種主+輔索引的好處是,當發生數據行移動或者頁分裂時,輔助索引樹不須要更新,由於輔助索引樹存儲的是主索引的主鍵關鍵字,而不是數據具體的物理地址。
那實際狀況,咱們通常選用哪一種引擎?
咱們通常使用Innodb,從mysql-5.5.5開始的版本 默認都是innodb引擎。他支持事務,支持行鎖,併發度高。儘可能不要混用引擎。