先來看看二叉樹
二叉樹是大家熟知的一種樹,用它來做索引行不行,可以是可以,但有幾個問題:
1. 如果索引資料很多,樹的層次會很高(只有左右兩個子節點),資料量大時查詢還是會慢
2. 二叉樹每個節點只儲存乙個記錄,一次查詢在樹上找的時候花費磁碟io次數較多
所以它並不適合直接拿來做索引儲存,演算法設計人員在二叉樹的基礎之上進行了變種,引入了b樹的概念
如上圖可知btree有以下特點:
1.不再是二叉搜尋,而是n叉搜尋,樹的高度會降低,查詢快
2.葉子節點,非葉子節點,都可以儲存資料,且可以儲存多個資料
3.通過中序遍歷,可以訪問樹上所有節點
當我們利用索引查詢的時候,不可能把整個索引全部載入到記憶體裡,能做的只有逐一載入每乙個磁碟頁,這裡的磁碟頁對應著索引樹的節點,也就是說索引樹越低,我們的進行的磁碟io數就越少,也就越能提高效率
b樹被作為實現索引的資料結構被創造出來,是因為它能夠完美的利用「區域性性原理」,其設計邏輯是這樣的
1.記憶體讀寫快,磁碟讀寫慢,而且慢很多
2.磁碟預讀:磁碟讀寫並不是按需讀取,而是按頁預讀,一次會讀一頁的資料,每次載入一些看起來是冗餘的資料,如果未來要讀取的資料就在這一頁中,可以避免未來的磁碟讀寫,提高效率(通常,一頁資料是4k)
3.區域性性原理:軟體設計要盡量遵循「資料讀取集中」與「使用到乙個資料,大概率會使用其附近的資料」,這樣磁碟預讀能充分提高磁碟io效能
早先的mysql就是使用的btree做為索引的資料結構,隨著時間推移,b樹發生了較多的變種,其中最常見的就是b+tree變種,現在mysql用的就是這種,示意如下:
b+tree改進點及優勢所在:
1. 仍然是n叉樹,層級小,非葉子節點不再儲存資料,資料只儲存在同一層的葉子節點上,b+樹從根到每乙個節點的路徑長度一樣,而b樹不是這樣
2. 葉子之間,增加了鍊錶(圖中紅色箭頭指向),獲取所有節點,不再需要中序遍歷,使用鍊錶的next節點就可以快速訪問到
3. 範圍查詢方面,當定位min與max之後,中間葉子節點,就是結果集,不用中序回溯(範圍查詢在sql中用得很多,這是b+樹比b樹最大的優勢)
4. 葉子節點儲存實際記錄行,記錄行相對比較緊密的儲存,適合大資料量磁碟儲存;非葉子節點儲存記錄的pk,用於查詢加速,適合記憶體儲存
5. 非葉子節點,不儲存實際記錄,而只儲存記錄的key的話,那麼在相同記憶體的情況下,b+樹能夠儲存更多索引,意味著b+樹比b樹更矮,磁碟io次數越少
用通俗易懂的話,總結b+樹的優勢
b+樹的優勢:
1.單一節點儲存更多的元素,使得查詢的io次數更少。
2.所有查詢都要查詢到葉子節點,查詢效能穩定。
3.所有葉子節點形成有序鍊錶,便於範圍查詢。
來自:小灰
二叉搜尋樹 平衡二叉樹 B樹 B 樹 B 樹
二叉查詢樹,由於不平衡,如果連續插入的資料是有順序的 會導致如下圖b的所示,此時搜尋會退化到o n 二叉查詢樹,也稱二叉搜尋樹,或二叉排序樹。其定義也比較簡單,要麼是一顆空樹,要麼就是具有如下性質的二叉樹 1 若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值 2 若任意節點的右子樹...
二叉樹 B樹以及B 樹
資料庫索引結構一般引用b樹或者索引。利用樹結構的原因?樹結構查詢效率更高 節點按照順序排列 二叉樹結構 b樹結構 乙個m階的b樹具有如下幾個特徵 1.根結點至少有兩個子女。2.每個中間節點都包含k 1個元素和k個孩子,其中 m 2 k m 3.每乙個葉子節點都包含k 1個元素,其中 m 2 k m ...
二叉搜尋樹,B樹(B 樹),B 樹,B 樹
b樹即二叉搜尋樹 1.所有非葉子結點至多擁有兩個兒子 left和right 2.所有結點儲存乙個關鍵字 3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹 如 b樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則,如果查詢關鍵字比結點關鍵字小,就進入...