數據結構中常見的樹(BST二叉搜索樹、RBT紅黑樹、B-樹、B+樹、mysql索引實現原理)

BST樹

       即二叉搜索樹:

       1.所有非葉子結點至多擁有兩個兒子(Left和Right);

       2.所有結點存儲一個關鍵字;

       3.非葉子結點的左指針指向小於其關鍵字的子樹,右指針指向大於其關鍵字的子樹;

       如:

       BST樹的搜索,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中;

否則,如果查詢關鍵字比結點關鍵字小,就進入左兒子;如果比結點關鍵字大,就進入

右兒子;如果左兒子或右兒子的指針爲空,則報告找不到相應的關鍵字;

       如果BST樹的所有非葉子結點的左右子樹的結點數目均保持差不多(平衡),那麼B樹

的搜索性能逼近二分查找;但它比連續內存空間的二分查找的優點是,改變BST樹結構

(插入與刪除結點)不需要移動大段的內存數據,甚至通常是常數開銷;

       如:

      

   但BST樹在經過多次插入與刪除後,有可能導致不同的結構:

 

   右邊也是一個BST樹,但它的搜索性能已經是線性的了;同樣的關鍵字集合有可能導致不同的

樹結構索引;所以,使用BST樹還要考慮儘可能讓BST樹保持左圖的結構,和避免右圖的結構,也就

是所謂的“平衡”問題;      

      

RBT 紅黑樹

AVL是嚴格平衡樹,因此在增加或者刪除節點的時候,根據不同情況,旋轉的次數比紅黑樹要多;
紅黑是弱平衡的,用非嚴格的平衡來換取增刪節點時候旋轉次數的降低;
所以簡單說,搜索的次數遠遠大於插入和刪除,那麼選擇AVL樹,如果搜索,插入刪除次數幾乎差不多,應該選擇RB樹。

紅黑樹上每個結點內含五個域,color,key,left,right,p。如果相應的指針域沒有,則設爲NIL。
一般的,紅黑樹,滿足以下性質,即只有滿足以下全部性質的樹,我們才稱之爲紅黑樹:
1)每個結點要麼是紅的,要麼是黑的。
2)根結點是黑的。
3)每個葉結點,即空結點(NIL)是黑的。
4)如果一個結點是紅的,那麼它的倆個兒子都是黑的。
5)對每個結點,從該結點到其子孫結點的所有路徑上包含相同數目的黑結點。
下圖所示,即是一顆紅黑樹:



 

B樹

B-tree(多路搜索樹,並不是二叉的)是一種常見的數據結構。使用B-tree結構可以顯著減少定位記錄時所經歷的中間過程,從而加快存取速度。按照翻譯,B 通常認爲是Balance的簡稱。這個數據結構一般用於數據庫的索引,綜合效率較高。

B樹的特徵:
1. 根節點至少有兩個孩子
2. 每個非根節點有[ ,M]個孩;
3. 每個非根節點有[ -1,M-1]個關鍵字,並且以升序排列
4. key[i]和key[i+1]之間的孩子節點的值介於key[i]、key[i+1]之間
5. 所有的葉子節點都在同一層

例如下圖就是一棵B樹:

B樹的優勢在於多路查找,這便是優於紅黑樹的具體原因,我沒有具體的公式在這列出來,但是,想一想,我每個結點有多個key,而紅黑樹每個結點有一個key,那麼隨着數據的不斷增多,紅黑樹的高度不斷增加,效率不斷降低,而B樹的高度一般都很低,爲甚?我一個結點放上1024個key,滿了才分裂一次!

說到這裏就不得不提B樹的分裂;B樹爲甚會分裂? 因爲隨着數據的增多,一個結點的key滿了,爲了保持B樹的特性,就會產生分裂,就向紅黑樹和AVL樹爲了保持樹的性質需要進行旋轉一樣!

正如前言所說的,這裏不會對樹的那些具體性質進行詳細的說明,因爲那樣有些累,所以,爲什麼叫探索B樹/B+樹與MySQL數據庫索引的關係,前提是你已經直到什麼是B/B+樹纔有資格去更深的探索!

B+樹

B-Tree有許多變種,其中最常見的是B+Tree,例如MySQL就普遍使用B+Tree實現其索引結構。

與B-Tree相比,B+Tree有以下不同點:

每個節點的指針上限爲2d而不是2d+1。

內節點不存儲data,只存儲key;葉子節點不存儲指針。

例如下圖就是一棵B+樹:


 

所有的key都會在葉子結點命中,我覺得這是B+樹的最大的特點,當然,請記住這一特點,因爲在後面的時候會用到;

細心的你發現,在葉子結點之間有一個指針相互連接,在現在的數據庫中幾乎都是這樣設計的B+樹,因爲這樣可以方便遍歷;

而B+樹相對於B樹的話更容易確定一個區間的值,如果你瞭解B+樹的性質的話會很快明白這一特性的;

下面是參考圖:

MyISAM和InnoDB

MyISAM 和 InnoDB 是MySQL的兩代搜索引擎;
區別在於,對於輔助索引的實現原理不一樣,並且MyISAM是索引和文件分離的,而InnoDB不是;

一般以主鍵爲索引的叫做主索引,而以其他鍵爲索引的叫做輔助索引;

直接上MyISAM的實現原理,利用B+樹實現,

由上圖可以看出,col1是主鍵,而葉子結點存儲的數據是一個地址,通過地址找到數據;

下面是輔助索引(和主索引不同的是輔助索引的key是可以重複的)


仔細對照MyISAM的這兩張圖,看看有什麼主索引和輔助索引有什麼區別?

下面看看InnoDB B+樹實現

這是主索引,即利用主鍵構造的B+樹;

注意,和MyISAM不同的是葉子結點的數據域保存的是全部數據;

下面在看輔助索引:

仔細看輔助索引和主索引的區別,輔助索引的葉子結點保存的是主鍵;這就是MyISAM和InnoDB最大的不同;

既然MyISAM和InnoDB是MySQL的兩代引擎,肯定會有一個提升,而InnoDB是最新一代,那麼它到底優在哪裏?

試想,MyISAM和InnoDB都是以B+樹爲基礎實現的,相對於B樹的不同其實前面已經講過,即數據域和結點分離;

而MyISAM更是索引和文件分離,B+樹的葉子結點的數據域存放的是文件內容的地址,主索引和輔助索引的B+樹都是如此,那麼如果我改變了一個地址,是不是所有的索引樹都得改變,正如前面我們講的在磁盤上頻繁的讀寫操作是效率很低的,而這塊又不適用局部原理,因爲邏輯上相鄰的結點,物理上不一定相鄰,那麼這樣就會造成效率上的降低;

於是乎,InnoDB就產生了,它讓除了主索引以外的輔助索引的葉子結點的數據域都保存主鍵,先通過輔助索引找到主鍵,然後通過主鍵找到葉子結點的所有數據,聽起來貌似很麻煩,遍歷了兩棵樹,但是,這樣如果有了修改的話,改變的只是主索引,其它輔助縮印都不用動,而且,數據庫中的樹的每一個結點的key可不是咱們給的那麼少,試想如果一個結點有1024個key,那麼高度爲2的B+樹都有1024*1024個key,所以一般樹的高度都很低,所以,遍歷樹的消耗幾乎忽略不計!

 

文章轉自:https://blog.csdn.net/bitboss/article/details/53219945

 

 

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