理論是灰色的,實踐之樹長青? ——恩格斯mysql這樣的關係型資料庫在查詢方面有一些重要特性,是kv型的資料庫或者 快取所不具備的,比如:
(1)範圍查詢。
(2)字首匹配模糊查詢。
(3)排序和分頁。
這些特性的支援,要歸功於b+樹這種資料結構。下面我們來分析一下b+樹是如何支援這些特性的。
這裡我們拿資料庫主鍵對應的b+樹邏輯結構來說明,這個結構有幾個關鍵特性:
下面的結構圖可以更好的說明這兩個特性:
基於這樣乙個資料結構以上特性就更好說明了:
另外,基於b+樹的特性,會發現對於offset這種特性,其實是用不到索引的。比如每頁顯示10條資料,要展示第101頁,通常會寫成select *** where *** limit 1000, 10,從offset = 1000的位置開始取10條。 雖然只取了10條資料,但實際上資料庫要把前面的1000條資料都遍 歷才能知道 offset =1000的位置在哪。對於這種情況,合理的辦法是不 要用offset,而是把offset = 1000的位置換算成某個max_id,然後用where 語句實現,就變成了select *** where *** and id > max_id limit 10,這樣 就可以利用b+樹的特性,快速定位到max_id所在的位置,即是 offset=1000所在的位置。
上面的樹只是乙個邏輯結構,最終要儲存到磁碟上。下面就以 mysql中最常用的innodb引擎為例,看一下如何實現b+樹的儲存。
對於磁碟來說,不可能一條條地讀寫,而都是以「塊」為單位進行讀 寫的。innodb預設定義的塊大小是16kb,通過innodb_page_size引數指 定。這裡所說的「塊」,是乙個邏輯單位,而不是指磁碟扇區的物理塊。 塊是innodb讀寫磁碟的基本單位,innodb每一次磁碟i/o,讀取的都是 16kb的整數倍的資料。無論葉子節點,還是非葉子節點,都會裝在 page裡。innodb為每個page賦予乙個全域性的32位的編號,所以innodb 的儲存容量的上限是64tb(2^30×16kb)。
16kb是乙個什麼概念呢?如果用來裝非葉子節點,乙個page大概 可以裝1000個key(16k,假設key是64位整數,8個位元組,再加上各種 其他字段),意味著b+樹有1000個分叉;如果用來裝葉子節點,乙個 page大概可以裝200條記錄(記錄和索引放在一起儲存,假設一條記錄大概100個位元組)。基於這種估算,乙個三層的b+樹可以儲存多少資料 量呢?如圖下圖所示:
把第一層和第二層的索引全裝入記憶體裡,即(1+1000)×16kb,也 即約16mb的記憶體。三層b+樹就可以支撐2億條記錄,並且一次基於主 鍵的等值查詢,只需要一次i/o(讀取葉子節點)。由此可見b+樹的強 大!
基於page,最終整個b+樹的物理儲存類似下圖所示:
page與page之間組成雙向鍊錶,每乙個page頭部有兩個關鍵字段: 前乙個page的編號,後乙個 page 的編號。page 裡面儲存一條條的記 錄,記錄之間用單向鍊錶串聯,最終所有的記錄形成上面所示的雙向 鍊錶的邏輯結構。對於記錄來說,定位到了page,也就定位到了page裡 面的記錄。因為page會一次性讀入記憶體,同乙個page裡面的記錄可以在 記憶體中順序查詢。
在innodb的實踐裡面對於非主鍵索引,同上面類似的結構,每乙個非主鍵索引對應一顆 b+樹。在innodb中,非主鍵索引的葉子節點儲存的不是記錄的指標, 而是主鍵的值。所以,對於非主鍵索引的查詢,會查詢兩棵b+樹,先 在非主鍵索引的b+樹上定位主鍵,再用主鍵去主鍵索引的b+樹上找到 最終記錄。
有一點需要特別說明:對於主鍵索引,乙個key只會對應一條記 錄;但對於非主鍵索引,值可以重複。所以乙個key可能對應多條記 錄,如下表所示。假設對於欄位1建立索引(欄位1是乙個字元類 型),乙個a會對應1,5,7三條記錄,c對應8、12兩條記錄。這反映在 b+樹的資料結構上面就是其葉子節點、非葉子節點的儲存結構,會和 主鍵索引的儲存結構稍有不同。
主鍵id
欄位1(非主鍵索引)
其他欄位1a
5a7a
8c10b
12c非主鍵索引的b+樹結構如下圖所示:
首先,每個葉子節點儲存了主鍵的值;對於非葉子 節點,不僅儲存了索引欄位的值,同時也儲存了對應的主鍵的最小值。
索引之B樹 B 樹 B 樹 B 樹詳解
索引之b樹 b 樹 b 樹 b 樹 b樹 即二叉搜尋樹 1.所有非葉子結點至多擁有兩個兒子 left和right 2.所有結點儲存乙個關鍵字 3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹 如 b樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則...
B 樹,B 樹,B 樹詳解
1970年,r.bayer和e.mccreight提出了一種適用於外查詢的樹,它是一種平衡的多叉樹,稱為b樹 或b 樹 b 樹 1 根結點至少有兩個子女 2 每個非根節點所包含的關鍵字個數 j 滿足 m 2 1 j m 1 3 除根結點以外的所有結點 不包括葉子結點 的度數正好是關鍵字總數加1,故內...
B樹 B 樹 B 樹詳解
b樹 b 樹 是一種多路搜尋樹 並不是二叉的 1.定義任意非葉子結點最多只有m個兒子 且m 2 2.根結點的兒子數為 2,m 3.除根結點以外的非葉子結點的兒子數為 m 2,m 4.每個結點存放至少m 2 1 取上整 和至多m 1個關鍵字 至少2個關鍵字 5.非葉子結點的關鍵字個數 指向兒子的指標個...