索引可能有三種數據結構哈希表、有序數組和N叉樹。MySQL使用了B+樹。
1.哈希表(散列表)
哈希表是一種以鍵 - 值(key-value)存儲數據的結構,我們只要輸入待查找的值即 key,就可以找到其對應的值即 Value。
因爲是使用hash算法對key求值取餘得到其在數組的存儲位置。
所以,哈希表這種結構適用於只有等值查詢的場景,比如 Memcached 及其他一些 NoSQL 引擎。在範圍查詢中需要全表掃描,是很慢的。
2.有序數組
有序數組在範圍查詢中優勢非常明顯,可以採用二分法,能大大縮短查詢時間,尤其是數據量比較大時。時間複雜度是時間複雜度是 O(log(N))。如果往中間插入一條數據,就需要把後續數組都往後移,這個時候有序數組的成本就很高了.
所以,有序數組索引只適用於靜態存儲引擎,
3.二叉樹(N叉樹)
根據葉子節點的內容,索引類型分爲主鍵索引和非主鍵索引。
主鍵索引的葉子節點存的是整行數據。在 InnoDB 裏,主鍵索引也被稱爲聚簇索引(clustered index)。
非主鍵索引的葉子節點內容是主鍵的值。在 InnoDB 裏,非主鍵索引也被稱爲二級索引(secondary index)。
基於主鍵索引和普通索引的查詢有什麼區別?
主鍵索引的葉子節點存的是整行數據。如果查詢條件是主鍵就能獲取整行數據。非主鍵索引的value是主鍵Id,如果查詢條件是非主鍵,那麼先查非主鍵索引得到主鍵id,根據主鍵Id再查主鍵索引得到整行數據。
從性能和存儲空間方面考量,自增主鍵往往是比業務字段更合理的選擇。可以參考:優化 | InnoDB表一定要用自增列做主鍵
有沒有什麼場景適合用業務字段直接做主鍵的呢?還是有的。比如,有些業務的場景需求是這樣的:
-
只有一個索引;
-
該索引必須是唯一索引。
你一定看出來了,這就是典型的 KV 場景。
由於沒有其他索引,所以也就不用考慮其他索引的葉子節點大小的問題。