關(guān)于B-樹問題的演示圖解

大家好,我是“Stephen·謝”,之前有講到樹(Tree)的概念,還演示了二叉查找樹和紅黑樹這兩種經(jīng)典樹的相關(guān)內(nèi)容,其中引入了一個“自平衡”的概念,這個自平衡特性對樹結(jié)構(gòu)而言相當(dāng)?shù)闹匾?,它是使我們的樹結(jié)構(gòu)變得實用方便的重要手段。由此,開始下面B樹(B-Tree即Balance Tree)的講解。


首先補充一點,標(biāo)題中的"B-樹"就是“B樹”,它們都是B-Tree的翻譯,里面不是減號-,是連接符-。因為有人把B-Tree讀成"B-樹",讓人誤以為“B樹”和"B-樹"是兩種樹,實際上兩者都是同一種樹。還有,大家在讀的時候千萬不要讀成“B減樹”,讀成“B樹”就行了,不然就外行了。

下面開始今天正文,我們依然從數(shù)據(jù)庫的檢索開始,我們知道數(shù)據(jù)庫的索引是使用樹結(jié)構(gòu)來實現(xiàn)的,是因為樹的查詢效率高,而且還可以保持有序的狀態(tài)。上篇中講到的二叉查找樹效率就很高,但是為什么沒有使用二叉查找樹來實現(xiàn)索引呢?其實從算法邏輯上講,二叉查找樹的查找次數(shù)和比較次數(shù)都是最小的,但是我們必須還要考慮一個現(xiàn)實問題:磁盤的IO(磁盤讀寫)。

數(shù)據(jù)庫的索引是存儲在磁盤上的,當(dāng)數(shù)據(jù)量非常大的時候,索引的大小可能有幾個G甚至更多,當(dāng)我們利用索引查詢的時候顯然不可能將整個索引全部加載到內(nèi)存,正常的操作都是逐一加載每一個磁盤頁,這里的磁盤頁就對應(yīng)著索引樹的節(jié)點。


索引樹和磁盤頁

我們?nèi)绻枚娌檎覙渥鏊饕Y(jié)構(gòu),查找情形是什么樣子的呢?假設(shè)樹的高度是4,要查找的值是10。

以此二叉查找樹為例查10
這是第1次和第2次磁盤IO的結(jié)果
這是第3次和第4次磁盤IO的結(jié)果

磁盤IO的次是4次,即樹的高度,最壞的情況就是磁盤IO的次數(shù)等于索引樹的高度。既然如此,為了減少磁盤IO的次數(shù),我們就需要把原來的“瘦高”樹結(jié)構(gòu)變得“矮胖”,這就是本文所要說的B-樹的特征之一。

B-樹(以下都稱作B樹)是一種多路平衡查找樹,它的每個節(jié)點最多包含k個孩子,其中,k被稱為B數(shù)的階,k的大小取決于磁盤頁的大小。

一個m階的B樹具備如下幾個特征:

1、根節(jié)點至少有兩個子女;

2、每個中間節(jié)點都包含k-1個元素和k個孩子,其中m/2<=k<=m;

3、每個葉子節(jié)點都包含k-1個元素,其中m/2<=k<=m;

4、所有的葉子節(jié)點都位于同一層;

5、每個節(jié)點中的元素從小到大排列,節(jié)點當(dāng)中k-1個元素正好是k個孩子包含的元素的值域劃分。

我們以一個3階B樹為例來看一下B樹的結(jié)構(gòu),樹中的具體元素和上面的二叉查找樹是一樣的。

3階B樹

我們來看(2,6)節(jié)點,該節(jié)點有兩個元素2和6,又有三個孩子1,(3,5),8。其中1小于元素2,(3,5)在元素2,6之間,8大于元素6,符合上面的幾條規(guī)則。

(2,6)分支

接下來我們來看一下B樹的查詢過程,看看會帶來什么效果,假如我們要查詢的數(shù)值是5

第1次磁盤IO
在內(nèi)存中定位(和9比較)
第2次磁盤IO
在內(nèi)存中定位(和2,6比較)
第三次磁盤IO
在內(nèi)存中定位(和3,5比較)

從上面我們看出,其實B樹在查詢中的比較次數(shù)并不比二叉查找樹少,尤其當(dāng)單一節(jié)點中的元素數(shù)量很多時??墒窍鄬Υ疟PIO的速度,在內(nèi)存中比較耗時幾乎可以忽略,所以只要樹的高度足夠低,磁盤IO次數(shù)足夠少,就可以提高查詢性能。就算單個節(jié)點內(nèi)元素多一點也沒關(guān)系,僅僅是多了幾次內(nèi)存中的交互,可以忽略用時。其實說白了B樹的優(yōu)勢和高效就是因為B樹將一部分的IO負(fù)擔(dān)到內(nèi)存中來了,用內(nèi)存的高效和強大提升了查詢性能。


下面我們來看一下B樹的插入和刪除

B樹插入新節(jié)點的過程比較復(fù)雜,分好多種情況,此處舉一個最典型的例子,還使用上面的B樹,假如我們要插入的值是4,自頂向下查找4的位置,發(fā)下4應(yīng)當(dāng)插入到節(jié)點元素3,5之間,

插入4

可是節(jié)點3,5已經(jīng)是兩節(jié)點元素,無法再增加,父節(jié)點2,6也是兩節(jié)點元素,無法再增加。倒是根節(jié)點9是單元素節(jié)點,可以升級為兩元素節(jié)點,于是拆分節(jié)點2,6和節(jié)點3,5,讓根節(jié)點9升級為兩元素節(jié)點4,9,節(jié)點6獨立為根節(jié)點的第二個孩子。

插入4后的B樹

由此看出,插入一個節(jié)點,會讓B樹的那么多節(jié)點發(fā)生連鎖改變。也正是如此,保證了B樹始終維持多路平衡,這就是B樹的一大優(yōu)勢,也是B樹英語Balance-Tree中Balance的體現(xiàn)。

下面再看看B樹的刪除機制,以上面插入4后的B樹為例,刪除元素11,首先自頂向下找出11的位置

自頂向下找出11的位置

刪除11后,節(jié)點12只有一個孩子,不符合B樹規(guī)范,因此找出12,13,15三個節(jié)點的中位數(shù)13,取代節(jié)點12,而節(jié)點12自身下移成為第一個孩子。(此過程稱為“左旋”)

刪除11
左旋完成



以上便是B樹的查詢,新增和刪除的機制,B樹主要應(yīng)用于文件系統(tǒng)(FS)以及部分?jǐn)?shù)據(jù)庫索引,比如著名的非關(guān)系型數(shù)據(jù)庫MongoDB。但是絕大多數(shù)關(guān)系型數(shù)據(jù)庫,比如MySQL,都使用B+樹作索引,所以下篇將會介紹B+樹的相關(guān)內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結(jié)點至多有m個孩子。 除根結(jié)點和葉子結(jié)點外,其它每個結(jié)點至少有m...
    文檔隨手記閱讀 13,666評論 0 25
  • 原文鏈接 B樹 1.前言: 動態(tài)查找樹主要有:二叉查找樹(Binary Search Tree),平衡二叉查找樹(...
    非典型程序員閱讀 1,255評論 0 3
  • B樹 1.前言: 動態(tài)查找樹主要有:二叉查找樹(Binary Search Tree),平衡二叉查找樹(Balan...
    鐵甲依然在_978f閱讀 1,524評論 0 4
  • 深秋,北京又籠罩在霧霾之下,身體帶有著些許不適,可抱怨已經(jīng)減少了很多,甚至可以把霧霾的天氣當(dāng)作笑話來談。 我有點咳...
    FreeManFree閱讀 314評論 0 0
  • 無論春夏秋冬,這里窗外總能聽見鳥兒鳴叫,尤其是上午時分,只要你想聽。當(dāng)然我不知道那是什么鳥,以我的常識,只認(rèn)...
    lenmon928閱讀 250評論 0 0

友情鏈接更多精彩內(nèi)容