數據庫索引(B樹,B+樹,哈希)

本文轉載自:數據庫索引(B樹,B+樹,哈希)

數據庫索引是存儲引擎用於快速找到記錄的一種數據結構。-----《高性能MySQL》

什麼是索引?

索引的目的就是便於快速查找。一本書的索引就是目錄,可以讓我們快速定位到要查找的內容;數據庫的數據是以記錄的方式存在的,所以索引的目的就是便於查找某一些記錄。

索引類型:
  • 唯一索引:不允許其中任何兩行具有相同值的索引
    使用主鍵和候選鍵建立的索引就是唯一索引,因爲主鍵和候選鍵都可以確定唯一一個元組,即一張表中不存在相同的主鍵和候選鍵。在MySQL中,當你建立一個主鍵和候選鍵之後,MySQL會爲它們分別建立索引。畢竟要想滿足唯一性,依然會在更新數據的時候檢驗是否已經存在該主鍵或者候選鍵,而索引無疑是快速檢驗的標配。

  • 主鍵索引:可以認爲是特殊的唯一索引,僅利用主鍵建立的索引

  • 單一索引:任何一個單一數據項建立的索引
    假如有下表【country,city,personNumber】,如果我們想查詢某個國家的人數,我們就應當以國家建立索引,這樣單一數據項建立的索引就是單一索引。

  • 複合索引:多個數據項建立的索引
    假如有下表【country,city,personNumber】,如果我們想查詢某個城市的人數,我們就應當以【country,city】建立索引,多個數據項建立索引的時候,我們應當指定其排序的先後順序,此處國家應優先排序,城市次之。

  • 聚簇索引:利用主鍵建立的索引,其物理存放順序與主鍵順序一致。因爲數據只有一個物理存放順序,所以一個表只有一個聚簇索引。
    在MySQL中,選定主鍵之後將會自動爲主鍵創建索引。該索引可以維護主鍵的唯一性。非葉子節點包含了主鍵值,而葉子節點則指向了一條完整的記錄。

  • 非聚簇索引(二級索引,輔助索引):除了聚簇索引之外,其餘所有的索引都是非聚簇索引
    非聚簇索引爲什麼是二級索引呢?重點在於一個二字。可以料想如果WHERE條件不是根據主鍵進行索引,那麼我們就需要基於該非主鍵建立的索引進行檢索,這樣建立的索引葉子節點中包含了記錄的主鍵,再使用主鍵在聚簇索引中找尋到完整的記錄。可以說進行了兩次B+ Tree查找而不是一次

  • 覆蓋索引:一個索引包含(覆蓋)所要查詢的字段的值,注意覆蓋索引與具體的查詢有關
    假如有下表【country,city,personNumber】,如果我們想查詢某個城市的人數,覆蓋索引指的是可以將你想要查詢的列建立在一個索引中,如(國家,城市,人數)作爲一個複合索引,此時查找某一個國家的所有城市利用索引就可以完成,實際上這也相當於完成了聚簇索引的功能

如何快速找到記錄?

說到查找算法,最樸實的就是無序排列的遍歷了。在數據量較小的時候(PS:如果數據量較小我想數據庫也不會有這麼快的發展),此方法也不失爲一種好的方法,畢竟沒有相應數據結構的維護,插入更新數據的時候就可以再快一點。在學習算法的書籍中,數據結構總也是扮演着重要的角色。無序排列的數據簡直就是一種佛系的數據結構,不管不顧它就是那樣。一個好的算法基於一個合適的數據結構的例子比比皆是,堆排序基於堆這種數據結構;二叉搜索基於一棵構建好的二叉搜索樹,哈希查找基於哈希表……所以數據庫中爲了快速查找到需要的記錄也需要選擇合適的數據結構。

什麼樣的數據結構適合作爲索引?

下面就介紹幾種數據庫中快速查找記錄的數據結構:

B+ Tree索引

在這裏插入圖片描述以上爲一個3階的B+ Tree,其上的數字我們可以認爲使用ID建立起來的單一索引。如果需要使用如下SQL語句進行查詢:

SELECT * FROM STUDENTS WHERE ID=1

這個查詢語句只需要三次查找就可以找到ID爲1的葉子節點,找到存放該條記錄(存放了ID爲1的學生的所有屬性)的物理地址,進而找到該條數據。

B+ Tree索引優點
  • 全值匹配:指的是和索引中所有列進行匹配。假設以(姓,名,出生日期)三個數據項建立複合索引,那麼可以查找姓名爲張三,出生日期在2000-12-12的人
  • 匹配最左前綴:假設以(姓,名,出生日期)三個數據項建立複合索引,可以查找所有姓張的人
  • 匹配列前綴:假設有姓爲司徒,司馬的人,我們也可以查找第一列的前綴部分,如查找所有以司開頭的姓的人
  • 匹配範圍值:可以查找所有在李和張之間的姓的人,注意範圍查詢只在複合索引的優先排序的第一列。(假設姓名按照拼音排序)
  • 精確匹配前面列並範圍匹配後一列:可以查找姓名爲張三並出生日期在2000-12-12之後的人,注意第一個範圍查詢後面的列無法再使用索引查詢
  • 只訪問索引的查詢:即查詢只需訪問索引,而無需訪問數據行。(此時應想到索引中的覆蓋索引)

B+ Tree索引缺點

  • 如果不是按照索引的最左列開始查找,則無法使用索引。如無法查找名爲龍的人,也無法查找在2000-12-12之後出生的人,當然也無法查找姓中以龍結尾的人(注意爲和含有的區別)
  • 不能跳過索引中的列:無法查找姓李並在2000-12-12之後出生的人
  • 如果查詢中包括某個列的範圍查詢,則其右邊所有列都無法使用索引優化查詢
B Tree索引

在這裏插入圖片描述
關於B樹和B+樹的區別,可參考:面試官問你B樹和B+樹,就把這篇文章丟給他
總結摘錄一下:
B+樹相對於B樹有一些自己的優勢,可以歸結爲下面幾點。

  • 單一節點存儲的元素更多,使得查詢的IO次數更少,所以也就使得它更適合做爲數據庫MySQL的底層數據結構了。
  • 所有的查詢都要查找到葉子節點,查詢性能是穩定的,而B樹,每個節點都可以查找到數據,所以不穩定。
  • 所有的葉子節點形成了一個有序鏈表,更加便於查找。
哈希索引

在這裏插入圖片描述
對於hash索引,一個好的hash函數非常重要。

哈希索引優點

  • 快速查詢:參與索引的字段只要進行Hash運算之後就可以快速定位到該記錄,時間複雜度約爲1

哈希索引缺點

  • 哈希索引只包含哈希值和行指針,所以不能用索引中的值來避免讀取行
  • 哈希索引數據並不是按照索引值順序存儲的,所以也就無法用於排序和範圍查詢
  • 哈希索引也不支持部分索引列查詢,因爲哈希索引始終是使用索引列的全部數據進行哈希計算的。
  • 哈希索引只支持等值比較查詢,如=,IN(),<=>操作
  • 如果哈希衝突較多,一些索引的維護操作的代價也會更高
發佈了114 篇原創文章 · 獲贊 148 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章