樹(四)詳解B+樹與B樹索引

目錄

1 從B樹說起

1.1 B樹的特點

1.2 一棵五叉B樹會有哪些特點

2 構造一棵B樹

2.1 準備數據

2.2 插入前四個元素

2.3 插入第五個元素

2.4 插入第六至第八的元素

2.5 插入第九個元素

2.6 插入第十至十三的元素

2.7 插入第十四元素

2.8 插入第十五個元素

2.9 插入第十六個元素

2.10 插入第十七個元素

2.11 插入最後兩個元素

3 B+樹

3.1 B+樹的特點

3.2 構造一棵B+樹

3.2 爲什麼Mysql使用B+樹作爲索引


1 從B樹說起

        Mysql有兩種類型的索引,一種是HASH,一種是BTREE,大多數時候我們都選擇BTREE索引。BTREE索引實際上是一個B+樹,對於B+樹的描述,先從B樹說起。

1.1 B樹的特點

        在寫B+樹之前先說B樹。首先,B樹不屬於二叉樹,它的節點可以擁有大於2的子節點。

        B樹是一種平衡的多叉樹,也稱爲多路平衡搜索樹,一棵m叉的B樹具有如下特點。

      (1)樹中的每一個節點最多包含m個子節點;

      (2)所有的葉子節點處於同一層;

      (3)除根節點與葉子節點外,每個節點至少包含ceil(m/2)個子節點,這裏ceil表示向上取整(比如一個7叉B樹,每個節點至少包含ceil(7/2) = 4個子節點);

      (4)當根節點不是葉子節點時,根節點至少要有2個子節點;

      (5)每個非葉子節點由n個key與n+1個指針組成,其中ceil(m/2)-1 <= n <= m-1。

1.2 一棵五叉B樹會有哪些特點

        這裏以一棵5叉B樹舉例。對於5叉B樹,根據上面的定義,它會具有以下性質。

      (1)樹中的每一個節點最多包含5個子節點;

      (2)所有的葉子節點處於同一層;

      (3)除根節點與葉子節點外,每個節點至少包含3個子節點;

      (4)當根節點不是葉子節點時,根節點至少要有2個子節點;

      (5)每個非葉子節點由n個key與n+1個指針組成,這裏的指針指向子節點,並且2 <= n <= 4。

 

2 構造一棵B樹

        B樹的構造與平衡二叉樹不一樣,平衡二叉樹向下插入子節點並通過旋轉等操作保持平衡,而B樹以向上分裂的方式構造。

2.1 準備數據

        這裏準備了19個元素元素,會以順序插入的方式構造一棵5叉B樹,數據如下。

2, 13, 6, 1, 7, 4, 10, 16, 12, 5, 14, 17, 11, 15, 3, 8, 9, 18, 19

2.2 插入前四個元素

        在插入前四個元素[2, 13 , 6, 1]後這棵樹只有一個節點,在這個節點上有4個key,5個指針,4個key爲一個節點的最大容量,下面爲圖示。

2.3 插入第五個元素

        上面的節點中已經有了四個元素,此時插入第五個元素[7],發生向上分裂。以目前的[1, 2, 6, 7, 13]的中間元素向上分裂重寫構造,比[6]小的元素作爲左子樹節點中的元素,比[6]大的元素作爲右子樹節點中的元素,下面爲圖示。

2.4 插入第六至第八的元素

        接着插入第六至第八的元素[4, 10, 16],此時根節點的右子樹會達到單個節點的最大元素數量4個,下面爲圖示。

2.5 插入第九個元素

        插入第九個元素,也就是[12],此時根節點的右子樹節點向上分裂,將中間元素[12]放入根節點,並將[7, 10]兩個元素放到同一個節點,[13, 16]放到另一個節點中,下面爲圖示。

2.6 插入第十至十三的元素

        插入第十至十三的元素[5, 14, 17, 11]四個元素,這四個元素插入後,依然是一棵B樹,不會發生向上分裂,下面爲圖示。

2.7 插入第十四元素

        插入第十四個元素[15],此時發生向上分裂,[15]這一個元素正好是[13, 14, 15, 16, 17]的中間元素。向上分裂之後,根節點的元素爲[6, 12, 15],該節點有四個子節點,下面爲圖示。

2.8 插入第十五個元素

        插入第十五個元素[8],此時再次向上分裂,[1, 2, 3, 4, 5]的中間元素爲[3],因此將[3]拿到根節點,[1, 2]作爲單獨一個節點, [4, 5]爲另一個節點,以下爲圖示。

2.9 插入第十六個元素

        插入第十六個元素[8],不發生分裂,下面爲圖示。

2.10 插入第十七個元素

        插入第十七個元素[9],[7, 8, 9, 10, 11]這個節點達到了五個元素向上分裂,取中間元素[9]向上分裂,此時[3, 6, 9, 12, 15]這個節點,也就是根節點元素數量到達五,需要將[9]這一個元素向上分裂,作爲根節點,圖示如下。

 

2.11 插入最後兩個元素

        插入最後兩個元素,此時不發生分裂,完成B樹的構造,下面爲圖示。

 

3 B+樹

        從上面對B樹的構造過程可以看到,B樹的層級少,所以它的查詢效率是比較高的;另外,在插入與刪除數據的時候對於整棵樹的結構影響較小,這也是它的優點。

        接下來說B+樹。

3.1 B+樹的特點

        B+樹衍生自B樹,它的特點如下:

      (1)一棵m叉B樹的每個節點最多是有m-1個key,而B+樹每個節點最多可以有m個key;

      (2)B樹的key在樹中有序排列在每一個節點中,而B+樹的所有key都在葉子節點中有序排列;

      (3)B+樹的所有非葉子節點都是爲了查找到葉子節點。

      (4)B+樹的葉子節點處於同一層,並且相鄰的葉子節點互相連接,使所有葉子節點形成一個鏈表。

3.2 構造一棵B+樹

        這裏我畫了一棵四叉B+樹,直接上圖。

         在這棵樹中,可以通過索引(非葉子節點)找到葉子節點,葉子節點包含了這棵樹的所有key,並且是有序的;另外,在每一個葉子節點也可以通過鏈表找到其他的葉子節點。

3.2 爲什麼Mysql使用B+樹作爲索引

        (1)選用B+樹作爲索引穩定且效率高,這是由於B+樹所有數據都在葉子節點中,並且所有葉子節點處於同一層;

        (2)B+樹對於新增與修改節點的效率也是比較高的,這與B樹相同;

        (3)在葉子節點引入了鏈表,增加範圍查詢的效率,比如我要查詢上圖四叉B+樹中[11]到[24]的數據,那麼在根據索引(非葉子節點)找到[11]所在的葉子節點後,也可以根據鏈表找到其他葉子節點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章