為什么MySQL數據庫要用B+樹存儲索引


 

A:為什么MySQL數據庫要用B+樹存儲索引?

Hash的查找速度為O(1),而樹的查找速度為O(log2n),為什么不用Hash作為數據庫的存儲索引呢?

樹的話,無非就是前中后序遍歷、二叉樹、二叉搜索樹、平衡二叉樹,更高級一點的有紅黑樹、B樹、B+樹。

【紅黑樹】

紅黑樹也是平衡樹中的一種,它復雜的定義以及繁瑣的規則無非就是為了保證樹的平衡性。一棵紅黑樹可以保證平衡性,保持平衡性的目的無非就是降低樹的高度,提高搜索效率,Java中的TreeSet就是基於紅黑樹實現的

 

【B樹】

B樹就是多路搜索樹,B樹的每個節點都可以擁有多余兩個孩子節點,比如一棵M路的B樹最多可能擁有M個孩子節點。如下圖,是一棵三路的B樹,每個節點組多擁有三個孩子節點,同樣是一棵搜索樹。

路數越多,樹的高度越低,但是不能無限增加路數,那樣B樹會退化成有序數組。

B樹主要用在文件系統的索引上,為什么不用紅黑樹或者有序數組做文件系統的索引呢?要知道,文件系統和數據庫的索引都是存在硬盤上的,並且如果數據量大的話,不一定能一次性加載到內存中。

如果一棵樹無法一次性加載到內存中的話,B樹多路存儲的能力就顯現出來了,這時候可以每次加載樹的一個節點,接着慢慢往下找。

比如下圖的有序數組,如果內存每次只能加載兩個數,這么長的數組是無法一次性加載到內存中的

如果把上圖的有序數組轉換成一棵三路的B樹,這樣每個節點最多能存儲2個數

這樣,查找的時候一次只需要加載一個節點進內存就可以了

B樹在磁盤的操作上較紅黑樹更有優勢,而在內存中,紅黑樹比B樹效率更高

【B+樹】

B+樹是在B樹的繼承上進行改造,它的數據都存儲在葉子節點上,同時葉子節點之間還加了指針形成鏈表。下圖是一棵四路B+樹,它的數據都存儲在葉子節點上,並且有鏈表相連

B+樹的使用場景在數據庫的索引上使用的比較多,這個也是跟業務系統有關的,使用數據庫進行數據查找的時候,一般select查找的數據不止一條,有時候會有很多條檢索結果,比如按照id排序后選10條。如果是多條的話,B樹需要做局部的中序遍歷,可能要跨層訪問。而B+樹由於所有數據都在葉子結點,不用跨層,同時由於有鏈表結構,只需要找到首尾,通過鏈表就能把所有數據取出來了。比如選出7和19,只需要在葉子節點中就能找到

 

回到問題,為什么MySQL數據庫要用B+樹存儲索引?

這和業務場景有關。如果只選一個數據,那確實是Hash更快。但是數據庫中經常會選擇多條,這時候由於B+樹索引有序,並且又有鏈表相連,它的查詢效率比Hash就快很多了。而且數據庫中的索引一般是在磁盤上,數據量大的情況可能無法一次裝入內存,B+樹的設計可以允許數據分批加載,同時樹的高度較低,提高查找效率。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM