1. 程式人生 > 其它 >B-tree和B+tree的區別

B-tree和B+tree的區別

二叉查詢樹:

特性:左子樹的鍵值小於根的鍵值,右子樹的鍵值大於根的鍵值,下圖是一個二叉查詢樹

對該二叉樹進行查詢發現深度為1的節點查詢次數是1,深度為2的查詢次數為2,查詢為n的節點查詢次數為n,因此平均查詢次數為(1+2+2+3+3+3)/6=2.3次。

二叉樹可以任意的構造,同樣是2,3,5,6,7,8這幾個數字,可以構造為

但是這顆二叉樹的效率就低了,所以需要這棵樹是平衡的,就有了平衡二叉樹,或叫AVL樹。

平衡二叉樹

平衡二叉樹在符合二叉樹查詢條件下,還滿足任何節點的兩個子樹的高度的最大差為1,下邊這兩張圖,左邊是AVL樹,右邊是非AVL樹。

平衡多路二叉樹(B-Tree)

多路:即節點不再是多個子節點,可以有多個

B-Tree是為磁碟等外部裝置設計的一種平衡查詢樹

系統從磁碟讀取資料到記憶體是以磁碟塊(block)為基本單位的,位於同一個磁碟塊的資料會被一次性讀取出來,而不是需要什麼取什麼。

而innodb儲存引擎有頁(page)的概念,頁是其磁碟管理的最小單位。innodb儲存引擎中預設每頁的大小為16K,可以通過引數innode_page_size將頁的大小設定為4K、8K、16K。

而一個磁碟的儲存空間往往沒這麼大,因此innodb每次申請磁碟空間時都會是若干地址連續磁碟塊來達到頁的大小16K。

innodb在把磁碟資料讀入到磁碟時會以頁為基本單位,在查詢資料時,如果一個頁中的每條資料都能有助於定位資料記錄的具體位置

,那麼將會減少磁碟I/O的次數,提高查詢效率。

B-Tree結構的資料可以讓系統高效的找到資料所在的磁碟塊。

以下為每頁的結構:

每個節點佔用一個盤塊的磁碟空間,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指標, 指標儲存的是指標所在磁碟塊的地址。

兩個關鍵詞劃分成的三個範圍域對應三個指標指向的子樹的資料的範圍域,以根節點為例:關鍵字為17和35,P1指向指標的子樹的資料範圍為小於17,P2指標指向的子樹的資料範圍為17-35,P3指標指向的子樹的資料範圍為大於35。

模擬查詢關鍵字29的過程:

  1. 根據根節點找到磁碟塊1,讀入記憶體【磁碟I/O為第一次】
  2. 比較關鍵字29在區間[17-35],找到磁碟塊1的指標P2
  3. 根據P2的指標找到磁碟塊3,讀入記憶體【磁碟I/O為第二次】
  4. 比較關鍵字29在區間(26-30),找到磁碟塊3的指標P2
  5. 根據P2指標找到磁碟塊8,讀入記憶體【磁碟I/O為第三次】
  6. 在磁碟塊8的關鍵字列表中找到關鍵字29

分析上面過程,需要3次I/O操作和3次記憶體查詢操作,由於記憶體中的關鍵字是一個有序表結構,可以利用二分法查詢提高效率。而三次磁碟I/O操作是影響B-Tree查詢的決定因素。B-Tree相對於AVL-Tree縮減了節點個數,使每次磁碟I/O取到記憶體的資料都發揮了作用,從而提高了查詢效率。

B+Tree(balance+tree)

B+Tree是B-Tree的一種優化,使其更適合實現外儲存資料結構,innodb儲存引擎就是用B+Tree實現其結構。

B-Tree結構圖中可以看到每個節點中不僅包含資料的key值,還有data值(非葉子節點也有),而每個頁的儲存空間是有限的。

如果data資料較大時將會導致每個節點(即一個頁)能儲存的key的數量很小。

當儲存的資料量很大時同樣會導致B-Tree的深度較大,增加磁碟I/O的次數,進而影響查詢效率。

在B+Tree中,所有資料記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只儲存key值資訊,這樣可以大大加大每個節點儲存key值數量,降低B+Tree的高度。

且B+Tree的所有關鍵字的具體資訊都儲存在葉子節點,通常都會使用連結串列將葉子節點連線起來,遍歷葉子節點就能夠獲取所有的資料,也就可以進行區間查詢,而B-Tree只有中序遍歷才能夠獲取所有資料。

1.提高深度,提高儲存量

2.適合區間查詢

參考地址:

https://www.cnblogs.com/shengguorui/p/10695646.html

https://www.cnblogs.com/yanze/p/9908138.html