1.mysql索引類型
1.1B-樹索引
(B-樹就是所說的B樹)
使用樹狀結構存儲數據庫索引可以保證有序性而且查詢效率也很高,但是為什么數據庫的索引沒有使用二叉查找樹O(logN)來實現數據庫的索引那?因為我們不得不考慮一個很現實的問題那就是數據庫的索引是存儲在硬盤上的,當數據量比較大的時候,索引甚至可能有幾個G,我們無法將索引一次加入到內存當中,只能逐頁的加載每一個磁盤頁。最壞的情況下磁盤IO的次數就是樹的深度。為了減少磁盤IO次數我們就要降低樹的高度。
B樹是一種多路平衡查找樹,它的每一個結點最多包含K個孩子,k稱為B樹的階,k取決于磁盤頁的大小。
1.1.1一個m階的B樹必須滿足以下條件:
1.根結點至少有兩個子女。
2.每個非葉子節點都包含k-1個元素和k個孩子,其中 m/2 <= k <= m
3.每一個葉子節點都包含k-1個元素,其中 m/2 <= k <= m
4.所有的葉子結點都位于同一層。
5.每個節點中的元素從小到大排列,節點當中k-1個元素正好是k個孩子包含的元素的值域分劃。
1 2 3 5 6 8 9 11 12 13 15
m=3;
k={2,3}
非葉子節點孩子={2,3}
非葉子節點元素={1, 2}
葉子節點元素= {1,2}
利用這種特性可以減少磁盤IO的次數,雖然可能查詢的次數變多一點但是相比于磁盤IO的速度內存耗時幾乎可以忽略不計。
1.1.2B樹如何插入刪除
假如要插入4
自上到下查找發現3<4<=5,但是節點3,5已經是兩元素節點,無法再增加。父親節點 {2,6 }也是兩元素節點,也無法再增加。根節點9是單元素節點,可以升級為兩元素節點。于是拆分節點{3,5}與節點{2,6},讓根節點9升級為兩元素節點{4,9}。節點6獨立為根節點的第二個孩子。
雖然很復雜但是這也是B樹的優勢:自平衡
假如要刪除11
刪除11后,節點12只有一個孩子,不符合B樹規范。因此找出12,13,15三個節點的中位數13,取代節點12,而節點12自身下移成為第一個孩子。(這個過程稱為左旋)
1.2B+樹
當索引項比較多的時候,不能一次裝入內存,可以對索引再建立索引,形成多級索引。
1.2.1B+樹的特征
一個m階的B+樹具有如下幾個特征:
除了和B樹有相同的特征外B+樹還要滿足以下的特征
1.非葉子節點包含有k個元素(B樹中是k-1個元素),每個元素不保存數據,只用來索引,所有數據都保存在葉子節點。m/2<=k<=m
2.所有的葉子結點中包含了全部元素的信息,及指向含這些元素記錄的指針,且葉子結點本身依關鍵字的大小自小而大順序鏈接。
3.所有的非葉子節點元素都同時存在于子節點,在子節點元素中是最大(或最小)元素
在B+樹中所有的葉子節點覆蓋所有的數據記錄,而非葉子節點只保存了索引,B樹要所有的節點才能覆蓋所有的數據記錄。而且B+樹的葉子節點形成了一個有序的鏈表。
1.2.2B+樹的優勢
- 單行查詢
因為B+樹的非葉子節點并不存儲數據記錄,而是只存儲索引所以相同大小的磁盤也可以存儲更多的節點元素,所以在單行查詢時磁盤IO的次數更少。并且B+樹查詢最終查詢必須在葉子節點上,而B樹最好的情況只查詢根節點,最壞要要查詢葉子節點,所以B+樹是穩定的而B樹是不穩定查詢。 - 范圍查詢
B+樹只需要定位到最小的元素,然后遍歷葉子節點的鏈表就能查詢到所有的元素,而B樹要每次都從上到下依次前序遍歷到每一個元素。 - 總結:
單一節點存儲更多的元素,使得查詢的IO次數更少。
所有查詢都要查找到葉子節點,查詢性能穩定。
所有葉子節點形成有序鏈表,便于范圍查詢。
1.2.3插入和刪除
B+樹的插入和刪除和B+樹類似,最重要的區別就是節點指針的調整。
注:這里只是介紹了最常用兩種索引原理,其他索引將在后面穿插介紹。