最通俗易懂的數據庫索引結構講解


一般一個數據庫系統包含以下:

  • 存儲(文件系統):將設備持久化到存儲設備當中

  • 程序實例:對存儲進行邏輯上的管理

    • 物理存儲關係的存儲管理模塊
    • 優化執行效率的緩存模塊
    • 對sql語句進行解析的SQL解析模塊
    • 記錄操作的日誌管理模塊
    • 進行多用戶管理的權限劃分模塊
    • 災難恢復模塊容災機制
    • 優化查詢效率的索引模塊
    • 支持併發操作的鎖模塊

一、爲什麼要使用索引

首先我們要明白,數據庫的數據是存儲在磁盤中的,每次讀磁盤都是非常昂貴的的IO開銷,而且速度非常慢,所以現在的系統都有局部讀取的功能,能夠將我們所要的數據的周圍的數據一併讀取,但是這些還不能夠滿足我們,仍然會出現一次查詢需要多次IO,畢竟在沒有索引的情況下,我們每次查詢數據庫基本都是全表查詢,數據量少還好說,數據量稍微大些,不僅影響性能還浪費時間。所以索引就出現了。

二、索引有哪些類型呢(以mysql爲例)

  • 普通索引:最基本的索引,它沒有任何限制,用於加速查詢。INDEX
  • 唯一索引:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。UNIQUE INDEX
  • 主鍵索引:是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值。一般是在建表的時候 同時創建主鍵索引。PRIMARY KEY
  • 組合索引:指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引纔會被使用。使用組合索引時遵循最左匹配原則(後邊講解)。INDEX name(“colum_name”,“colum_name”…)
  • 全文索引:主要用來查找文本中的關鍵字,而不是直接與索引中的值相比較。FULLTEXT INDEX name("")

三、索引的數據結構

1、二叉查找樹進行二分查找

結構圖:
在這裏插入圖片描述
可以看出,二叉查找樹的左子節點的值是小於他的父節點的,例如上圖中2小於5,右子節點均大於父節點的值。

到這裏我們應該能夠明白,二叉查找樹結構的索引查找方法了,比如我們查找6,6>5,所以找5的右節點,6<7找7的子節點,以此類推,便可定位到,可以看出,他是對半搜索,所以時間複雜度爲O(logn)。

缺點

  • 節點刪除添加,會破壞其結構,可能會變成線性結構,那麼其複雜度可能會變爲O(n),大大降低了效率
  • 就算我們花費手段將其結構還原,我們可以看到,每個節點只能有兩個節點,也就是說,一次查詢可能需要較多的深度查找,這種做法增加了IO負擔,浪費資源,也耗時。是不滿足我們的優化查詢需求。

所以爲了提高效率,我們儘量降低深度,增大每個節點的子節點。由此,我們引出B-Tree

2、B-Tree結構

也稱作平衡多路查找樹在這裏插入圖片描述
實際中,每個索引子節點上限是大於3的,每個存儲塊(節點)包括關鍵字(藍色)和指向孩子的指針(黃色),能夠有多少個孩子,取決於存儲塊的容量和數據庫的相關配置

定義:

  • 根節點至少包括兩個孩子
  • 樹中每個節點最多含有m個孩子(m>=2)
  • 除了根節點和葉節點外,其他每個節點至少有m/2個孩子
  • 所有葉子節點都位於同一層(葉子節點的高度都是一樣的)

其餘特點:

  • 關鍵字個數永遠比指針少一個
  • 左子節點關鍵字的值都會比該節點的父節點關鍵字值小,右子節點均大於父節點關鍵字值,其餘子節點關鍵字值位於父節點關鍵字值開區間之內,例如圖上的9和10位於(8,12)

查詢B數結構的索引時,也是比較簡單明瞭的,比如我們查15,小於根節點的所有值,故查詢左邊,發現大於8和12,於是查詢右邊,15>13,繼續右邊,然後定位了。

優點:

  • 高度比二叉樹矮得多
  • 添加或刪除時,因爲有其定義在,B數可以進行上移下移來保證結構完整性,避免發展成線性結構
  • 時間複雜度:O(logb(n)),b爲分叉數

3、B+Tree(主流)

B+數是B數的變體,基本定義和B數相同

在一個磁盤塊中,關鍵字數目跟指針數目是一樣的
在這裏插入圖片描述
其特性跟B數也有點小區別

  • 父節點關鍵字最小值<=左子節點值<父節點中間節點值
  • 父節點關鍵字最大值<=右子節點值
  • 父節點關鍵字其餘值<=其餘子節點值<父節點最大值
  • 非葉子節點只存儲關鍵字,數據只能存儲在葉子節點中,也就是說哪怕在非葉子節點查詢到了,也必須進入他的葉子節點
  • 所有葉子節點均由一個鏈指針指向下一個葉子節點,順序由小向大連接,方便我們進行統計。比如我們查找到關鍵字爲10的葉子節點,我們需要統計>=10的數據,直接統計後邊連接的就行,就無須回到非葉子節點層進行搜索

B+樹的優點:

  • 除了葉子節點,其餘節點只存儲關鍵字,這樣一個磁盤塊所能容納的關鍵字就越多,一次能夠查找的關鍵字就越多。也就是提高了磁盤IO性能
  • B+樹查詢效率更加穩定,都是需要查詢到葉子節點
  • B+樹更有利於對數據庫的掃描,葉子節點順序相連,更有利於數據庫範圍查詢,效率更高

4、 Hash

在這裏插入圖片描述

hash索引效率非常高,一次計算就可以找到目標,時間複雜度O(1)

缺點:

  • 僅僅滿足“=”,“IN”,不能使用範圍查詢
  • 不能利用部分索引鍵查詢,無法用組合索引
  • 不能避免表掃描
  • 遇到大量Hash值相等的情況後性能低下

它的侷限性還是很大的

索引是建得越多越好嗎

答案肯定是否。

  • 數據量小的表不需要建立索引,建立會增加額外的索引開銷

  • 數據變更需要維護索引,因此更多的索引意味着更多的維護成本

  • 索引是存儲在磁盤上的,更多的索引頁意味着需要更多的磁盤空間

    注意:

    1、索引需要佔用磁盤空間,因此在創建索引時要考慮到磁盤空間是否足夠

    2、創建索引時需要對錶加鎖,因此實際操作中需要在業務空閒期間進行

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