資料結構和演算法之八 B 樹

2021-10-06 13:09:44 字數 2020 閱讀 2641

如果僅僅是在記憶體中進行操作,那麼紅黑樹是完全能夠滿足我們的要求的,但是如果資料量到達非常龐大的量級,比如幾千萬上億時,我們是很難將資料全部load到記憶體中,構建出紅黑樹來直接查詢,那麼必定會將大量資料存放到磁碟上,在查詢時通過磁碟i/o來完成。

我們假設現在有1000萬資料,如果用紅黑樹來處理的話,那麼樹高估計在23-24層,如果1000萬資料都在記憶體中,我們可以看到,一次查詢只需要執行20多次搜尋比較就可以完成查詢,效率是極高的;但是1000萬資料全部放到記憶體中也不現實,因此實際的做法是,只把根節點載入到記憶體,其他資料放到磁碟上;在執行查詢時,如果比根節點小,則再從磁碟載入左孩子節點,再比較,再載入,一直這樣執行到葉子節點。那麼你會發現,一次查詢,要經過20多次的磁碟i/o,我們知道磁碟i/o相對記憶體操作是非常低效的,20多次磁碟i/o是不能接受的。

為了解決大資料量下,資料存到磁碟時,查詢導致磁碟i/o次數過多帶來的效能問題,誕生了b+樹這種資料結構, 它是mysql資料庫的索引的結構。

首先我們來認識一下b+樹的結構

可以看到,它和二叉樹的不同點是,首先,每個節點不止存乙個值了,而是存多個值,乙個值可以將資料分成小於它的和大於它的兩半,那麼n值就可以將資料分為n+1個區間段了;另外乙個就是二叉只會分為兩個孩子,而b+樹可以最多可以有m個分叉;最後你會發現葉子節點之間通過雙向鍊錶連線起來,這是主要是為了實現如sql中的區間查詢功能。

綜合一下b+樹的特點,它有如下的一些性質

m階的b+tree:

(1)每個節點最多有m個子節點(m叉樹)(為什麼不是m+1個子節點,理論上不是分為m+1個段嗎?我認為這是乙個工程實踐問題,b+樹的上一層值會來自於下一層節點的最大或者最小值,因此它會存在乙個左右開閉問題,因此要麼是左邊,要麼是右邊會少乙個值區間)

(2)除根節點外,每個節點至少有m/2個子節點。

(3)根節點要麼是空,要麼是獨根,否則至少有2個子節點

(4)有k個子節點的節點必有k個關鍵碼:就是 有m個資料就有m個叉叉;

(5)葉節點的高度一致:這樣所有分支的查詢複雜度是一樣的。

基本認識了b+樹的結構之後,回到之前的問題,b+樹時怎麼解決大資料量下的查詢,導致磁碟i/o次數過多引起的效能問題?

先來點計算機的底層知識,計算機從磁碟讀取資料到記憶體中時,並不是乙個資料乙個資料的讀取,它有個乙個最小的讀取尺寸單位,叫頁,比如4kb,每次讀取都是4kb。

因此我們可以利用這個原理,將乙個節點的大小就設定為一次磁碟i/o讀取的4kb大小,對於整形的資料型別,通常占用的空間在4個位元組,那麼乙個節點可容納的資料量就是 4096 / (4+2) 差不多為700,這個2指的是指標占用的空間。在b+樹中,所有資料都存在葉子節點中,我們可以初略估算一下,只有兩層的b+樹,資料量級為700 * 700 = 49w,如果是3層的b+樹,量級為700 ^ 3 = 3.5億。換句話說,從3.5億的資料量中查詢只需要做3次磁碟i/o,從根到葉子節點,你說高效不高效。(ps:1. 以上的計算只是說明思路,實際的數值是有出入的;2. 實際工程實踐中,根節點通常是常駐記憶體,因此i/o還會少一次根的載入)

b+樹的查詢操作,和二叉樹差不多,元素先和根比較(因為每個節點的元素是排好序的,因此可以使用二分查詢),找到對應的區間,再往下一級區間去查詢,直到葉子節點為止。

插入操作比二叉樹時,多了節點**的操作,因為b+樹有個階的限制,當某個節點的數量大於階的限制時,會**成多個節點。反過來,如果刪除節點時,存在何必的動作。

道理雖懂,但是暫時還沒有動手自己寫一顆b+樹出來,所以也就暫時不貼**出來,有空的大神可以寫出來分享一下。

前面說了這麼多b+樹, 那麼b樹呢?

b樹在實際中使用較少(貌似還沒見過那兒直接使用的b樹),你可以把它看做是b+樹的過渡,因此對它有個了解即可。

它和b+樹有哪些區別呢?

它的所有節點都會儲存資料,而b+樹的所有資料都在葉子節點上,非葉子節點(也可以認為索引層)資料是冗餘的,下層節點的一些值。

它的葉子節點之間沒有雙向鍊錶連線,因此範圍查詢時麻煩的事情。

b+樹視覺化神器體驗:

b樹視覺化神器體驗:

資料結構之B 樹和B 樹

特意說明,本文只簡述b樹和b 樹的基本概念,並不涉及刪除,插入等操作 b樹中所有結點的孩子結點個數的最大值稱為b樹的階,通常用m表示,從查詢效率考慮,要求m 3。一顆m階的b樹應該滿足以下條件 每個結點最多有m個分支 而最少分支樹要看是否為根結點,如果是根結點且不是葉子結點,則至少有兩個分支,非根非...

資料結構之B樹和B 樹整理

又稱多路平衡查詢樹,所有結點的最大孩子數稱為階。一般用m來指代。b樹的性質 對於m階的b樹 每個結點最多有m棵子樹,自身最多有m 1個關鍵字 如果根結點不是終端結點,至少兩課子樹。除根結點外的所有非葉結點至少有 向上取整m 2 棵子樹,那麼也就是至少有 向上取整m 2 1個關鍵字。所有葉節點都位於同...

資料結構之B 樹 B 樹

b樹的概念是為了解決一些現實問題而提出的,當資料量太大時,而記憶體中又無法儲存這麼多的資料,那麼就需要將資料儲存在磁碟上,如果繼續採用平衡樹的方法就會帶來一些問題,平衡樹每個節點都會分為兩個節點,那麼當資料太大的時候,樹的高度也會不斷增減,io操作的次數也隨之增加,所以需要降低樹的高度,所以才有了乙...