1. 程式人生 > >關係資料庫索引底層(一)——B-Tree

關係資料庫索引底層(一)——B-Tree

B-Tree就是我們常說的B樹。B樹這種資料結構常常用於實現資料庫索引,因為它的查詢效率比較高。

 

磁碟IO與預讀

 

  磁碟讀取依靠的是機械運動,分為尋道時間、旋轉延遲、傳輸時間三個部分,這三個部分耗時相加就是一次磁碟IO的時間,大概9ms左右。這個成本是訪問記憶體的十萬倍左右;正是由於磁碟IO是非常昂貴的操作,所以計算機作業系統對此做了優化:預讀;每一次IO時,不僅僅把當前磁碟地址的資料載入到記憶體,同時也把相鄰資料也載入到記憶體緩衝區中。因為區域性預讀原理說明:當訪問一個地址資料的時候,與其相鄰的資料很快也會被訪問到。每次磁碟IO讀取的資料我們稱之為一頁(page)。一頁的大小與作業系統有關,一般為4k或者8k。這也就意味著讀取一頁內資料的時候,實際上發生了一次磁碟IO。

 

B-Tree與二叉查詢樹的對比

 

  我們知道二叉查詢樹查詢的時間複雜度是O(logN),查詢速度最快和比較次數最少,既然效能已經如此優秀,但為什麼實現索引是使用B-Tree而不是二叉查詢樹,關鍵因素是磁碟IO的次數。

 

  資料庫索引是儲存在磁碟上,當表中的資料量比較大時,索引的大小也跟著增長,達到幾個G甚至更多。當我們利用索引進行查詢的時候,不可能把索引全部載入到記憶體中,只能逐一載入每個磁碟頁,這裡的磁碟頁就對應索引樹的節點。

 

一、 二叉樹

 

我們先來看二叉樹查詢時磁碟IO的次:定義一個樹高為4的二叉樹,查詢值為10:

 

                                                            

 

 

 

第一次磁碟IO:

 

                             

 

 

 

 

 

 第二次磁碟IO

 

                               

 

 

 

第三次磁碟IO:

 

                                  

 

 

 

第四次磁碟IO:

 

                                    

 

從二叉樹的查詢過程了來看,樹的高度和磁碟IO的次數都是4,所以最壞的情況下磁碟IO的次數由樹的高度來決定。

 

從前面分析情況來看,減少磁碟IO的次數就必須要壓縮樹的高度,讓瘦高的樹儘量變成矮胖的樹,所以B-Tree就在這樣偉大的時代背景下誕生了。

 

二、B-Tree

 

m階B-Tree滿足以下條件:

 

1、每個節點最多擁有m個子樹

 

2、根節點至少有2個子樹

 

3、分支節點至少擁有m/2顆子樹(除根節點和葉子節點外都是分支節點)

 

4、所有葉子節點都在同一層、每個節點最多可以有m-1個key,並且以升序排列

 

 如下有一個3階的B樹,觀察查詢元素21的過程:

 

                                                                              

 

第一次磁碟IO:     

 

                                                           

 

第二次磁碟IO:

 

                                                  

 

這裡有一次記憶體比對:分別跟3與12比對

 

第三次磁碟IO:

 

                                                     

 

這裡有一次記憶體比對,分別跟14與21比對

 

從查詢過程中發現,B樹的比對次數和磁碟IO的次數與二叉樹相差不了多少,所以這樣看來並沒有什麼優勢。

 

但是仔細一看會發現,比對是在記憶體中完成中,不涉及到磁碟IO,耗時可以忽略不計。另外B樹種一個節點中可以存放很多的key(個數由樹階決定)。

 

相同數量的key在B樹中生成的節點要遠遠少於二叉樹中的節點,相差的節點數量就等同於磁碟IO的次數。這樣到達一定數量後,效能的差異就顯現出來了。

三、B樹的新增

在剛才的基礎上新增元素4,它應該在3與9之間:

                                 

                                     

                                     

 

四、B樹的刪除

 刪除元素9:

                                  

 

                                    

五、總結

  插入或者刪除元素都會導致節點發生裂變反應,有時候會非常麻煩,但正因為如此才讓B樹能夠始終保持多路平衡,這也是B樹自身的一個優勢:自平衡;B樹主要應用於檔案系統以及部分資料庫索引,如MongoDB,大部分關係型資料庫索引則是使用B+樹實現。