讀MySQL技術內幕 B+樹與算法筆記

讀MySQL技術內幕 索引與算法筆記。
B+樹的B不代表二叉(binary),而是代表平衡(balance),因爲B+樹最早是從平衡二叉樹演化而來,但是B+樹不是一個二叉樹。
B+樹索引並不能找到一個給定鍵值得具體行。B+樹索引能找到的只是被查找數據行所在的頁。然後數據庫通過把頁讀入內存,再在內存中進行查找,最後得到查找的數據。
平衡二叉樹定義:首先符合二叉查找樹的定義,其次必須滿足任何節點的左右兩個子樹的高度最大差爲1。

B+樹

B+樹是爲磁盤或其他直接存取輔助設備設計的一種平衡查找樹。它所有記錄節點都是按鍵值的大小順序存放在同一層的葉子節點上,由各葉子節點指針進行連接。
在這裏插入圖片描述

B+樹插入操作

B+樹的插入必須保證插入後葉子節點中的記錄依然排序。向B+樹插入數據時會有下表中三種情況,分別對應不同的插入算法。
在這裏插入圖片描述
並不是總是從中間階段開始分裂,這樣可能會導致頁空間的浪費,key如果是隨機生成的,則有可能從中間節點開始分裂,key如果是順序生成的,則直接創建一個新的頁。
下面實例演示B+樹的插入過程。

  1. Leaf Page沒滿且Index Page沒滿
    向前面的B+樹中插入鍵值28,可直接得到如下B+樹:
    在這裏插入圖片描述
  2. Leaf Page滿且Index Page沒滿
    再向該B+樹插入鍵值70,此時需要根據中間值60拆分葉子節點,得到如下B+樹:
    在這裏插入圖片描述
  3. Leaf Page滿且Index Page滿
    最後向該B+樹插入鍵值95,葉子節點和索引節點都需要拆分,得到如下B+樹:
    在這裏插入圖片描述
    爲了保持平衡對於新插入的鍵值可能需要做大量的拆分頁(split)操作。因爲B+樹結構主要用於磁盤,頁的拆分意味着磁盤的操作,所以應該在可能的情況下儘量減少頁的拆分操作。因此,B+樹同樣提供了類似於平衡二叉樹的旋轉(Rotation)功能。

B+樹刪除操作

B+樹使用填充因子(fill factor)來控制樹的刪除變化,50%是填充因子可設的最小值。B+樹的刪除操作同樣必須保證刪除後葉子節點中的記錄依然排序。B+樹的刪除操作需要考慮下表中的三種情況:
在這裏插入圖片描述
假設填充因子爲50%。先刪除鍵值70,符合表中第一種情況,得到如下B+樹:
在這裏插入圖片描述
再刪除鍵值25,還是屬於第一種情況
在這裏插入圖片描述
再刪除鍵值60的。刪除Leaf Page中鍵值爲60的記錄後,填充因子小於50%,這時需要做合併操作,同樣,在刪除Index Page中相關記錄後需要做Index Page的合併操作,與插入時的旋轉操作一樣,最後得到如下B+樹:
在這裏插入圖片描述

B+樹索引

在數據庫中,B+樹的高度一般都在2~4層,就是說查找某一鍵值的行記錄時最多隻需要2到4次IO。一般的機械磁盤每秒至少可以做100次IO,2~4次的IO意味着查詢時間0.02~0.04秒。

聚集索引

聚集索引是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的就是整張表的行記錄數據,也將聚集索引的葉子節點稱爲數據頁。這個特性決定了索引組織表中數據也是索引的一部分,左右兄弟節點的數據頁都通過一個雙向鏈表來進行鏈接。
​ 數據頁上存放的是完整的每行的記錄,而在非數據頁的索引頁中,存放的僅僅是鍵值及指向數據頁的偏移量,而不是一個完整的行記錄。
在這裏插入圖片描述
聚集索引的存儲並不是物理上連續的,而是邏輯上連續的。這其中有兩點,一是前面說過的頁通過雙向鏈表鏈接,頁按照主鍵的順序排序;另一點是每個頁中額記錄也是通過雙向鏈表進行維護的,物理存儲上可以同樣不按照主鍵存儲。

輔助索引

​葉子節點並不包含行記錄的全部數據,葉子節點除了包含鍵值以外,每個葉子節點中的索引行中還包含了一個書籤。該書籤用來告訴InnoDB存儲引擎哪裏可以找到與索引相對應的行數據。由於InnoDB存儲引擎表是索引組織表,因此InnoDB存儲引擎的輔助索引的書籤就是相應行數據的聚集索引鍵。
在這裏插入圖片描述
如果在一棵高度爲3的輔助索引樹中查找數據,那需要對這棵輔助索引樹遍歷3次找到指定主鍵,如果聚集索引樹的高度同樣爲3,那麼還需要對聚集索引樹進行3次查找,最終找到一個完整的行數據所在的頁,因此一共需要6次邏輯IO訪問以得到最終的一個數據頁。

參考:
MySQL技術內幕五:InnoDB的索引與算法
MySQL技術內幕讀書筆記(五)——索引與算法

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