1. 程式人生 > 其它 >MySQL索引原理(標貝科技)

MySQL索引原理(標貝科技)

B樹(balance tree)和B+樹,可以認為是N叉多路平衡排序查詢樹。

  這裡的N是相對於二叉樹中的二來說的,B樹和B+樹的典型應用場景是資料庫引擎的索引結構。但是從理論上講,二叉樹查詢速度和比較次數都是最小的,為什麼不用二叉樹呢?

  因為我們要考慮磁碟IO的影響,它相對於記憶體來說是很慢的。資料庫索引是儲存在磁碟上的,當資料量大時,就不能把整個索引全部載入到記憶體了,只能逐一載入每一個磁碟頁(對應索引樹的節點)。所以我們要減少IO次數,對於樹來說,IO次數就是樹的高度,而“矮胖”就是b樹的特徵之一,它的每個節點最多包含N個孩子,N稱為b樹的階,N的大小取決於磁碟頁的大小。

  

一個N階的B樹具有如下幾個特徵(括號內我給出了通俗的翻譯):

  1. 定義任意非葉子結點最多隻有N個兒子,且N>2(翻譯 :一個節點最多分N個叉,最少2個叉);
  2. 除根結點以外的非葉子結點的兒子數為[N/2, N],向上取整 (翻譯 :進一步限定了非根節點的分叉數目的最小值為N/2,為了防止形成二叉樹);
  3. 非葉子結點的關鍵字個數=兒子數-1 (翻譯 :限定子節點中的資料量,數量為分叉數-1);
  4. 所有葉子結點位於同一層(翻譯:廢話);
  5. k個關鍵字把節點拆成k+1段,分別指向k+1個兒子,滿足查詢樹的大小關係 (翻譯:同一級節點元素有序排列且左子<父<右子)。

簡化總結:

  1.   N階B樹根節點最少2個兒子節點;
  2.   非子節點兒子節點數目最少為N/2,最多為N;
  3.   兒子節點的key數量最多為N-1;
  4.   同一級節點元素有序排列且左子<父<右子

  

 如圖是一個3階段B樹,順便說明一下數字5的查詢過程:

  

 

 

  第一次磁碟IO,把9所在節點讀到記憶體,把目標數5和9比較,小,找小於9對應的左節點; 

      

 

 

  第二次磁碟IO,還是讀節點到記憶體,在記憶體中把5依次和2、6比較,定位到2、6中間區域對應的節點;

  第三次側排IO,讀取key3、5所在的節點,併成功查詢到5

  b樹的插入刪除元素操作: 
  比如我們要在下圖中插入元素4: 
      
1,首先自頂向下查詢找到4應該在的位置,即3、5之間; 
2,但是3階b樹的節點最多隻能有2個元素,所以把3、4、5裡面的中間元素4上移(中間元素上移是插入操作的關鍵); 
3,上一層節點加入4之後也超載了,繼續中間元素上移的操作,現在根節點變成了4、9; 
4,還要滿足查詢樹的性質,所以對元素進行調整以滿足大小關係,始終維持多路平衡也是b樹的優勢,最後變成這樣: 

再比如我們要刪除元素11: 
1,自頂向下查詢到11,刪掉它; 
2,然後不滿足b樹的條件了,因為元素12所在的節點只有一個孩子了,所以我們要“左旋”,元素12下來,元素13上去: 
 
這時如果再刪除15呢?很簡單,當元素個數太少以至於不能再旋轉時,12直接上去就行了。

 

 B+樹

  b+樹,是b樹的一種變體,查詢效能更好。m階的b+樹的特徵:

  1. 有n棵子樹的非葉子結點中含有n個關鍵字(b樹是n-1個),這些關鍵字不儲存資料,只用來索引,所有資料都儲存在葉子節點。
  2. 所有的葉子結點中包含了全部關鍵字的資訊,及指向含這些關鍵字記錄的指標,且葉子結點本身依關鍵字的大小自小而大順序連結。
  3. 所有的非葉子結點可以看成是索引部分,結點中僅含其子樹中的最大(或最小)關鍵字。
  4. 通常在b+樹上有兩個頭指標,一個指向根結點,一個指向關鍵字最小的葉子結點。
  5. 同一個數字會在不同節點中重複出現,根節點的最大元素就是b+樹的最大元素。

 

b+樹相比於b樹的查詢優勢:

  1. b+樹的中間節點不儲存資料,所以磁碟頁能容納更多節點元素,更“矮胖”;
  2. b+樹查詢必須查詢到葉子節點,b樹只要匹配到即可不用管元素位置,因此b+樹查詢更穩定(並不慢);
  3. 對於範圍查詢來說,b+樹只需遍歷葉子節點連結串列即可,b樹卻需要重複地中序遍歷,如下兩圖:

     

     

 

 

參考連線
  https://www.cnblogs.com/xueqiuqiu/articles/8779029.html