B樹與B+樹區別辨析

咱們都知道,innodb中的索引結構使用的是B+樹。B+樹是一種B樹的變形樹,而B樹又是來源於平衡二叉樹。相較於平衡二叉樹,B樹更適合磁盤場景下文件索引系統。那爲何B樹更適合磁盤場景,B+樹又在B樹基礎上作了什麼優化?抱着這些問題,本博客將深刻分析B樹和B+樹前因後果,其中會涉及到二叉排序樹和平衡二叉樹等數據結構。數據結構

二叉排序樹、平衡二叉樹、B樹和B+樹都是基於二分法的思路來優化查找的。性能

二叉排序樹

要談B樹,首先要理解平衡二叉樹。而平衡二叉樹又是從二叉排序樹優化而來。讓咱們追根溯源先看看二叉排序樹。這個數據結構很是容易理解,知足以下性質即爲一棵二叉排序樹優化

  • 若左子樹不爲空,則左子樹上全部結點值均小於它的根結點值;
  • 若右子樹不爲空,則右子樹上全部結點值均大於等於它的根結點值;
  • 左右子樹也分別是二叉排序樹。

中序遍歷一棵二叉排序樹能獲得一個遞增的有序序列指針

問題:二叉排序樹的查找性能受限於它的結構,若是結構合理,複雜度能達到二分法的複雜度,O(log2N);而在極端狀況下,往二叉排序樹中插入結點,會獲得一個單鏈表,這樣時間複雜度就是O(N)了。樹的高度越小,查找速度越快。blog

平衡二叉樹

爲了使二叉排序樹高度儘量小,平衡二叉樹誕生了,也成爲AVL樹。這種數據結構,是具有以下特徵的二叉排序樹:排序

  • 左子樹和右子樹深度之差絕對值不超過1;
  • 左子樹和右子樹也是平衡二叉樹。

平衡二叉樹經過「旋轉」操做來保證左右子樹深度之差小於等於1,從而保證樹的高度儘量小。索引

問題:雖然說平衡二叉樹能夠保證必定的查找效率。即使這樣,平衡二叉樹方法也只適用於存儲在內存中的較小的文件,若是是查找存放在外存中很大的文件,每訪問一個結點就須要進行磁盤IO,因爲節點衆多,開銷依然很大。內存

B樹

既然結點太多了,那將多個結點合成一個節點如何,是否能夠減小IO次數。這樣也至關於將二叉樹變成多叉樹。B樹也是基於這個思路來實現的,即一個結點包含多個關鍵字(表示要查找的目標數值)和多個指向子樹的指針。
對於一個m階的B樹,擁有以下特性:博客

  • 樹中每一個結點至多有m棵子樹;
  • 若根結點不是葉子結點,則至少有兩棵子樹;
  • 除了根結點之外的全部非終端結點,至少有m/2棵子樹;
  • 全部葉子結點都出如今同一層次上(這體現出平衡的特色),而且不帶信息,成爲失敗結點;
  • 全部非終端結點最多有m-1個關鍵字。

在實際的文件系統場景中,B樹的結點規模通常以一個磁盤頁爲單位,因此m值取決於磁盤頁大小innodb

結點結構以下所示

image

第一個元素n記錄當前結點的關鍵字數量。K1 - Kn 表示各個關鍵字,P0 - Pn 表示指向子樹根結點的指針。重要性質:Pi所指向子樹中全部結點關鍵字均大於Ki,而且小於Ki+1。B樹即是依據此性質來完成查找。

所以,B樹查找的過程與平衡二叉樹相似,無需贅述。可是插入和刪除不太同樣。

插入

以插入爲例,假設要向一個m階B樹插入某個關鍵字,B樹會先查找該關鍵字在最底層的位置,向對應的位置插入。同時保證結點數量不超過m-1,若是超過數量限制,則會進行結點「分裂」,以中間關鍵字爲界將結點一分爲二,並將中間關鍵字向上插入到雙親結點上,若雙親結點已滿,用一樣的方法繼續分解,直到分解到根節點,此時B樹高度加1。

刪除

對於刪除而言,同理,若是結點的關鍵字刪除後數量小於(m/2)-1則要進行「合併」結點的操做。除了刪除關鍵字,還須要刪除關鍵字鄰近的指針。例如刪除Ki時,也須要刪除Pi。這裏就有兩種狀況,若刪除的結點Pi是最低層,直接刪除Ki和Pi便可,由於指針指向null;若是不是,不能直接刪,由於Pi指向一棵子樹,這時須要將Pi指向的子樹裏最小的關鍵字與待刪除關鍵字互換,互換以後目標關鍵字必定是轉移到了最低一層,將其和相鄰指針刪除便可。

B+樹

B樹已是很優秀的數據結構了,爲何還須要B+樹呢?先來看看兩者的區別。B+樹是B樹的變形樹,它們的差別以下:

  • 有n棵子樹的結點中含有n個關鍵字;
  • 全部葉子結點中包含所有關鍵字信息,以及指向含有這些關鍵字記錄的指針,且葉子結點自己依關鍵字的大小自小而大順序連接;
  • 全部非終端結點能夠當作是索引部分,結點中僅含有其子樹中的最大或最小關鍵字(innodb中是最小關鍵字)

B+樹的隨機查找、插入和刪除過程基本與B樹相似

與B樹相比的優點

1.查詢的IO次數更少

其實上文在B樹中提到的關鍵字,不只僅只是數值,也包含具體的數據。讀取結點,也會把各個關鍵字對應的具體數據讀取出來。而在B+樹中對於非終端節點而言,每個關鍵字只是一個索引,不包含其它數據(只有終端結點纔會引用具體數據)。所以,在單個結點大小一致的前提下(取磁盤頁的大小),B+樹中每一個非終端結點結點能夠存儲更多元素,所以樹的分支會更多,更加矮胖,查詢的IO次數也更少。

2.查詢性能穩定

B樹查詢不一樣結點性能可能不同,由於目標元素可能位於根節點,也可能在葉子結點上。可是B+樹中有效結點必定在最低層,因此每次查找必須查到葉子結點,性能穩定。

3.便於範圍查詢

範圍查詢,B樹須要進行屢次二分查找。而B+樹只須要一次二分查找找到下限,以後再順着鏈表找到上限便可。葉子結點經過鏈表互相鏈接這一事實,決定了B+樹在範圍查詢上的優點。

綜上所述,在MySQL索引結構中使用B+樹性能要更優於B樹。

相關文章
相關標籤/搜索