1. 程式人生 > 實用技巧 >【深基13.例1】查詢

【深基13.例1】查詢

瞭解mysql常用索引結構

1:什麼是索引

MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。
簡單來說:索引是幫助MySQL高效獲取資料的排好序的資料結構 
複雜來說:資料庫在肩負著儲存資料之外,還要查詢資料,那麼如何查詢資料呢?最基本的,順序查詢,但是資料量較大時耗時(O(n)),
優化查詢方式,比如二分查詢,需要特定的資料結構支援,所以需要一種資料結構支援高階的搜尋演算法,這個資料結構就是索引。

2:索引用的什麼資料結構?為什麼用這種資料結構?

索引資料結構有:紅黑樹,Hash,B+tree,mysql中主流的便是b+tree,還有hash。
使用b+tree的原因主要是:資料庫讀取資料涉及到磁碟io, 這是從 對比二叉樹、b數、b-、b+ 得出來的最佳實踐 
  • 二叉搜尋樹
二叉搜尋樹的特點便是 :每一個父節點最多隻會有兩個子節點,每個節點的左兒子小於父節點,父節點又小於右兒子。

二叉樹.png

  • 紅黑樹

    R-B Tree,全稱是Red-Black Tree,又稱為“紅黑樹”,它一種特殊的二叉查詢樹。
    紅黑樹的每個節點上都有儲存位表示節點的顏色,可以是紅(Red)或黑(Black)

    (1)每個節點或者是黑色,或者是紅色。
    (2)根節點是黑色。
    (3)每個葉子節點(NIL)是黑色。 [注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
    (4)如果一個節點是紅色的,則它的子節點必須是黑色的。
    (5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

    注意:
    (01) 特性(3)中的葉子節點,是隻為空(NIL或null)的節點。
    (02) 特性(5),確保沒有一條路徑會比其他路徑長出倆倍。因而,紅黑樹是相對是接近平衡的二叉樹。

紅黑樹1.jpg

  • B-Tree
B樹的定義和性質:對於M階的B樹 (可理解為紅黑樹的橫向擴容)

每個結點至多擁有m棵子樹;
除了根結點以外,其餘每個分支結點至少擁有 m/2 棵子樹;
根結點至少擁有兩顆子樹(存在子樹的情況下);
所有的葉結點都在同一層上,其可以看作是外部結點,不包含任何資訊;
有 k 棵子樹的非葉子結點則其存在 k-1 個關鍵碼,關鍵碼按照遞增次序進行排列;
關鍵字數量需要滿足ceil(m/2)-1 <= n <= m-1;

B樹1.png
B樹2.png
樹B3.png

  • B+Tree(B-Tree變種)

    B+樹的性質(下面提到的都是和B樹不相同的性質)
    非葉子節點的子樹指標與關鍵字個數相同;
    非葉子節點的子樹指標p[i],指向關鍵字值屬於[k[i],k[i+1]]的子樹.(B樹是開區間,也就是說B樹不允許關鍵字重複,B+樹允許重複);
    為所有葉子節點增加一個鏈指標.
    所有關鍵字都在葉子節點出現(稠密索引). (且連結串列中的關鍵字恰好是有序的);
    非葉子節點相當於是葉子節點的索引(稀疏索引),葉子節點相當於是儲存(關鍵字)資料的資料層.
    適合於檔案系統
    

B+tree.png

和B-tree比較起來

非葉子節點不儲存data,只儲存索引(冗餘),可以放更多的索引
葉子節點包含所有索引欄位
葉子節點用指標連線,提高區間訪問的效能

B+tree-mysql.png

3:資料庫引擎

  • MyISAM儲存引擎索引實現

    MyISAM索引檔案和資料檔案是分離的(非聚集)
    檔案儲存在myi檔案
    

MyISAM.png

  • InnoDB索引實現(聚集)

    data儲存的是資料整行的全部資料,其索引樹的所有葉子節點儲存著整個表的所有資料
    表資料檔案本身就是按B+Tree組織的一個索引結構檔案
    聚集索引-葉節點包含了完整的資料記錄

    為什麼InnoDB表必須有主鍵,並且推薦使用整型的自增主鍵?
    內部要用做維護,用於構建b+tree
    但是假如建立的表沒有指明唯一主鍵,mysql內部會在表中嘗試去尋找一個唯一的列充當唯一主鍵
    如果沒能找到唯一的列充當唯一主鍵,它會預設新增一列唯一主鍵用於維護(類似oracle的rowId)

    為什麼非主鍵索引結構葉子節點儲存的是主鍵值?
    為了保證資料一致性和節省儲存空間(可以按照分散式事務理解一下)
    儲存主鍵值容易管理,方便更新刪除等操作

    為什麼不建議使用UUID等字串作為主鍵值?並且建議整型自增?
    1:uuid(字串) 佔空磁碟空間比整形資料大
    2:資料比較沒整型好,字母的比較等(比較大小的時候不好)
    3:自增的主鍵易於構建b+tree,字串大小不好計算,假如一開始一個節點中存在4,6的主鍵資料,如果字串長度比較出來是5,
    這時候它要插入4,6之間,可能導致節點分裂(或者節點已經滿了,要進行移動),為了滿足b+tree的特性,
    要進行點平衡處理(使用自增的話可能有效減少導致數分裂平衡等)所以建議使用自增(圖例可比較上面b+tree的圖)

InnoDB1.png

  • 聯合索引結構

聯合索引.png