索引(五)索引數據結構

數據庫索引,是數據庫管理系統中一個排序的數據結構,主要有
B樹索引Hash索引兩種

一:B樹索引

先來看下B樹索引結構實列

關於圖的說明如下:
左邊表示的是某個數據庫的數據表,一共有兩列七條記錄,最左邊的是數據記錄的物理地址(就是在硬盤的存儲位置)。爲了加快對Col2這一列的查找,可以創建一個如右邊所示的二叉查找樹,每個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就可以運用二叉查找在O(log2n)的複雜度內獲取到相應數據。

舉例子來看下,比如這樣的一個查詢
select * from tablename where Col2=5
這時候會先從Col2=34的根節點開始找,因爲5小於34,會進入到左邊的編號位22的子節點,依次向下推,就會找到Col2=5,這樣就比用5Col2中的每個數字來對比下要快的多了。

其實關於B樹,大多數用的是B樹的變種,主要有B-,B+樹,關於這兩個介紹,我幫大家找了兩篇以漫畫形式解釋這兩個概念的,比較容易理解,保證你看完後不會有這樣的感覺

兩篇通俗易懂的文章:
漫畫:什麼是B-樹?
漫畫:什麼是B+樹?

二:理解Hash樹索引

哈希索引就是採用一定的哈希算法,把鍵值換算成新的哈希值,檢索時不需要類似B+樹那樣從根節點到葉子節點逐級查找,只需一次哈希算法即可立刻定位到相應的位置,速度非常快。

Hash 索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位,這時疑問就來了,既然 Hash 索引的效率要比 B-Tree 高很多,爲什麼大家不都用 Hash 索引而還要使用 B-Tree 索引呢?任何事物都是有兩面性的,Hash 索引也一樣,雖然 Hash 索引效率高,但是 Hash 索引本身由於其特殊性也帶來了很多限制和弊端,主要有以下這些。

1.Hash索引只支持等值比較,例如使用=,IN( )和<=>。對於WHERE price>100並不能加速查詢

如果是等值查詢,那麼哈希索引明顯有絕對優勢,因爲只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

由於 Hash 索引比較的是進行 Hash 運算之後的 Hash 值,所以它只能用於等值的過濾,不能用於基於範圍的過濾,因爲經過相應的 Hash 算法處理之後的 Hash 值的大小關係,並不能保證和Hash運算前完全一樣。

2.Hash 索引無法被用來避免數據的排序操作

由於 Hash 索引中存放的是經過 Hash 計算之後的 Hash 值,而且Hash值的大小關係並不一定和 Hash 運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算;

3.Hash 索引不支持多列聯合索引的最左匹配規則

對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合併後再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。

4.Hash索引在任何時候都不能避免表掃描

前面已經知道,Hash 索引是將索引鍵通過 Hash 運算之後,將 Hash運算結果的 Hash 值和所對應的行指針信息存放於一個 Hash 表中,由於不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數據的記錄條數,也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數據進行相應的比較,並得到相應的結果。

B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因爲存在所謂的哈希碰撞問題。

補充:

什麼情況下會使用索引呢?

  1. 主鍵自動建立唯一索引

  2. 頻繁作爲查詢條件的字段應該創建索引

  3. 查詢中於其他表關聯的字段,外鍵關係建立索引

  4. 頻繁更新的字段不適合建立索引,因爲每次更新不單單時更新了記錄還會更新索引

  5. where 條件裏用不到的字段不創建索引

  6. 查詢中排序的字段,排序的字段若通過索引去訪問將會大大提高排序速度

  7. 查詢中統計或者分組的字段

哪些情況不需要創建索引

  1. 表記錄太少

  2. 經常增刪改的表

  3. 如果某個數據列包含許多重複的內容,爲它建立索引
    就沒有太多太大實際效果

關於這篇文章,希望大家能夠多理解幾遍,把索引的概念給吃透。

參考鏈接
1.數據庫索引B樹、B+樹、Hash索

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