一篇帶你了解數(shù)據(jù)庫索引的類型

數(shù)據(jù)庫索引是一種用于加快數(shù)據(jù)庫查詢速度的數(shù)據(jù)結(jié)構(gòu),它類似于書籍的目錄,可以幫助快速定位到表中某個(gè)或某些特定的行。數(shù)據(jù)庫索引通常由一組索引鍵(或索引字段)構(gòu)成,這些鍵的值被存儲(chǔ)在一個(gè)數(shù)據(jù)結(jié)構(gòu)中,以便快速查找特定的行。
索引的類型(實(shí)現(xiàn)方式)
數(shù)據(jù)庫索引有多種分類方法,從索引的實(shí)現(xiàn)方式常見的有:
- B+樹索引
- 哈希索引
- 空間索引(例如 R-樹)
- 全文索引
- Bitmap索引
每種索引類型適用于不同的數(shù)據(jù)類型和查詢類型,應(yīng)根據(jù)具體需求選擇合適的索引類型。
B+樹索引
B+樹是一種平衡樹,每個(gè)節(jié)點(diǎn)包含一定數(shù)量的關(guān)鍵字和指向子節(jié)點(diǎn)的指針,以支持快速的查詢和排序。B+樹索引適用于各種數(shù)據(jù)類型,并且支持范圍查詢和排序,因此在許多數(shù)據(jù)庫系統(tǒng)中廣泛使用。
B+樹索引示意圖

注: 圖片來源自Wikipedia(https://zh.wikipedia.org/wiki/File:Bplustree.png)
當(dāng)數(shù)據(jù)庫執(zhí)行查詢時(shí),它首先在B-樹索引中搜索包含查詢所需關(guān)鍵字的節(jié)點(diǎn),然后通過指針找到包含該關(guān)鍵字的數(shù)據(jù)記錄。如果查詢是范圍查詢,則B-樹索引還可以通過查詢包含范圍內(nèi)關(guān)鍵字的節(jié)點(diǎn),并返回所有符合條件的數(shù)據(jù)記錄。
B+樹索引的優(yōu)點(diǎn)
- 支持快速的查詢和排序,提高數(shù)據(jù)庫的性能。
- 支持各種數(shù)據(jù)類型,可以索引數(shù)值型,字符串型和日期/時(shí)間型數(shù)據(jù)。
- 可以處理大量的數(shù)據(jù),因?yàn)樗且环N平衡樹。
B+樹索引的缺點(diǎn)
- 在插入或刪除數(shù)據(jù)時(shí),B+樹可能需要重新平衡,以維護(hù)平衡樹的性質(zhì),因此插入或刪除操作可能會(huì)變慢。
- 在更新數(shù)據(jù)時(shí),需要?jiǎng)h除原來的數(shù)據(jù)記錄并創(chuàng)建新的數(shù)據(jù)記錄,因此可能會(huì)消耗大量的時(shí)間和空間。
Hash索引
Hash索引是一種基于哈希表的索引,它使用哈希函數(shù)將數(shù)據(jù)映射到哈希表中的桶(bucket)。
Hash索引示意圖

注: 圖片來源自Wikipedia(https://en.wikipedia.org/wiki/Hash_table)
當(dāng)數(shù)據(jù)庫執(zhí)行查詢時(shí),它使用哈希函數(shù)計(jì)算查詢所需關(guān)鍵字的哈希值,然后在哈希表中查找具有相同哈希值的數(shù)據(jù)記錄。如果發(fā)現(xiàn)多個(gè)數(shù)據(jù)記錄具有相同的哈希值,則必須使用比較運(yùn)算符來確定實(shí)際的數(shù)據(jù)記錄。
Hash索引的優(yōu)點(diǎn)
- 在查詢數(shù)據(jù)時(shí)非???,因?yàn)榭梢灾苯釉L問桶。
- 對(duì)于等值查詢特別有效,因?yàn)榭梢灾苯佣ㄎ恍枰臄?shù)據(jù)。
- 無需進(jìn)行排序,因此無需消耗額外的時(shí)間和空間。
Hash索引的缺點(diǎn)
- 不支持范圍查詢和排序。
- 哈希沖突可能導(dǎo)致查詢變慢,因?yàn)楸仨毷褂帽容^運(yùn)算符進(jìn)一步檢查數(shù)據(jù)記錄是否匹配。
- 不適用于所有數(shù)據(jù)類型,僅適用于數(shù)值型數(shù)據(jù)。
- 插入,更新和刪除操作可能需要重新散列,以維護(hù)哈希表的性質(zhì)。
空間索引
空間索引是一種專門用于處理空間數(shù)據(jù)的索引,通常用于地理信息系統(tǒng)(GIS)和空間數(shù)據(jù)庫中。它是用于快速查詢空間數(shù)據(jù)的位置和幾何關(guān)系的索引。
R-Tree示意圖

注: 圖片來源自Wikipedia
空間索引通常使用網(wǎng)格結(jié)構(gòu),如格網(wǎng)、網(wǎng)格圖或四叉樹,將空間數(shù)據(jù)劃分為許多小的網(wǎng)格單元。每個(gè)網(wǎng)格單元存儲(chǔ)其中的一個(gè)或多個(gè)數(shù)據(jù)點(diǎn),并使用空間算法快速查詢其他網(wǎng)格單元,以確定數(shù)據(jù)點(diǎn)的幾何關(guān)系。
空間索引的優(yōu)點(diǎn)
- 可以快速查詢空間數(shù)據(jù)的位置和幾何關(guān)系。
- 對(duì)于查詢空間數(shù)據(jù)的范圍,如矩形范圍、圓形范圍等,非常有效。
- 用于快速查詢數(shù)據(jù)的投影和視圖。
空間索引的缺點(diǎn)
- 比較復(fù)雜,需要許多空間算法的知識(shí)。
- 不適用于非空間數(shù)據(jù)。
- 當(dāng)數(shù)據(jù)數(shù)量很大時(shí),可能需要大量?jī)?nèi)存。
全文索引
全文索引是用于快速搜索文本內(nèi)容的索引。它可以在數(shù)據(jù)庫中搜索文本字段,或者在文檔管理系統(tǒng)中搜索文件內(nèi)容。全文索引通常通過對(duì)文本內(nèi)容進(jìn)行分詞(將文本分解為單詞),并使用數(shù)據(jù)結(jié)構(gòu)(如倒排索引)存儲(chǔ)分詞后的信息,以便快速查詢搜索詞。
全文索引的優(yōu)點(diǎn)
- 可以快速搜索文本內(nèi)容。
- 可以搜索模糊詞。
- 可以處理多語言文本。
全文索引的缺點(diǎn)
- 對(duì)于非文本數(shù)據(jù)不適用。
- 可能需要大量計(jì)算和存儲(chǔ)資源,特別是當(dāng)文本數(shù)據(jù)較大時(shí)。
- 可能存在誤判或誤識(shí)別情況。
位圖索引
Bitmap索引是一種特殊的數(shù)據(jù)索引,它通過將數(shù)據(jù)存儲(chǔ)為二進(jìn)制位映射(Bitmap)來加速查詢。每個(gè)位代表一個(gè)數(shù)據(jù)記錄是否符合某個(gè)特定條件。例如,如果某個(gè)位為1,則表示該記錄符合某個(gè)條件,如果為0,則表示該記錄不符合條件。
Bitmap索引的優(yōu)點(diǎn):
- 高效。Bitmap索引可以很快執(zhí)行大量的邏輯運(yùn)算,從而提高查詢效率。
- 空間效率。Bitmap索引在存儲(chǔ)數(shù)據(jù)時(shí)非常緊湊,因?yàn)樗恍枰鎯?chǔ)0和1的二進(jìn)制位。
Bitmap索引的缺點(diǎn):
- 數(shù)據(jù)更新困難。當(dāng)數(shù)據(jù)更改時(shí),需要重新生成整個(gè)Bitmap索引,這可能很耗時(shí)。
- 僅適用于特定類型的數(shù)據(jù)。Bitmap索引僅適用于具有限制類別數(shù)量的數(shù)據(jù),例如城市或性別等。
因此,Bitmap索引通常適用于具有較少不同值的列,以加速查詢。
其他分類
唯一索引
從唯一性的角度,索引可以分為唯一性索引和非唯一性索引。唯一性索引可以用來保證表中某個(gè)列的唯一性約束條件,通常用于實(shí)現(xiàn)主鍵約束和唯一性約束,數(shù)據(jù)庫通常會(huì)為主鍵或是唯一性約束自動(dòng)創(chuàng)建唯一性索引。
唯一性索引優(yōu)缺點(diǎn)
唯一性索引不僅可以提高查詢的效率,還可以起到數(shù)據(jù)校驗(yàn)的作用,避免了重復(fù)數(shù)據(jù)的產(chǎn)生,提高數(shù)據(jù)的質(zhì)量和準(zhǔn)確性。它的缺點(diǎn)是每當(dāng)有數(shù)據(jù)修改或是插入時(shí),需要檢查是否違反唯一性約束。
聚簇索引
從聚簇率的角度,索引可以分為聚簇索引或非聚簇索引。聚簇索引的索引鍵的排列順序和數(shù)據(jù)表中數(shù)據(jù)的排列順序一致的索引,每個(gè)表只能有一個(gè)聚簇索引,因?yàn)閿?shù)據(jù)表的數(shù)據(jù)只能以一種方式進(jìn)行排序。
在一些比較先進(jìn)的數(shù)據(jù)庫優(yōu)中,對(duì)于非聚簇索引也會(huì)計(jì)算其聚簇率,以方便優(yōu)化器評(píng)估回表時(shí)磁盤IO的代價(jià)。聚簇率小的索引回表時(shí),會(huì)引起磁盤IO的抖動(dòng),從而明顯影響查詢性能,一般來講,聚簇率越大,其磁盤IO的代價(jià)越小。
聚簇索引有兩種實(shí)現(xiàn)方式,
- 一是聚簇索引和表數(shù)據(jù)存儲(chǔ)在一起,索引樹中的每個(gè)葉子節(jié)點(diǎn)都存儲(chǔ)一個(gè)完整的表行,以MySQL的InnoDB引擎和SQL Server為代表。
- 二是聚簇索引和表的數(shù)據(jù)是分離的,可以先有表,然后定義聚簇索引,以DB2,PostgreSQL, Oracle為代表。
聚簇索引優(yōu)缺點(diǎn)
聚簇索引的優(yōu)勢(shì)是可以減少磁盤I/O次數(shù),從而提高查詢性能。但是,聚簇索引也有一些缺點(diǎn),譬如當(dāng)插入新數(shù)據(jù)時(shí),它可能需要移動(dòng)數(shù)據(jù)頁或重新組織索引,這可能會(huì)對(duì)性能產(chǎn)生負(fù)面影響。
二級(jí)索引
從是否是主鍵的角度,索引可以分為主鍵索引和二級(jí)索引,主鍵索引只能有一個(gè),二級(jí)索引可以有多個(gè)。
組合索引
從包含的索引列的數(shù)目的角度,索引可以分為單列索引和組合索引。組合索引可以滿足多種查詢條件,從而節(jié)省索引的空間和索引維護(hù)的代價(jià)。組合索引的匹配原則遵循最左前綴匹配原則,詳細(xì)信息請(qǐng)參考《如何創(chuàng)建高效的索引》。
函數(shù)索引
函數(shù)索引(或表達(dá)式索引)即基于函數(shù)或表達(dá)式的索引,它使用函數(shù)或是表達(dá)式提供計(jì)算好的值作為索引列構(gòu)建索引,可以在不修改應(yīng)用程序的情況下提高查詢性能。案例如下:
DAYOFMONTH是PostgreSQL自帶的函數(shù),它從日期中獲取天。
條件索引
部分索引(Partial index)是建立在一個(gè)表的子集上的索引,而該子集是由一個(gè)條件表達(dá)式定義的,該索引只包含表中那些滿足這個(gè)條件表達(dá)式的行。案例如下:
總結(jié)
- B+樹索引:B+樹索引是最常用的索引類型,具有平衡樹的性質(zhì),可以有效的維護(hù)大量的數(shù)據(jù),適用于大部分?jǐn)?shù)據(jù)類型,特別是數(shù)值型和字符串型數(shù)據(jù),并且支持區(qū)間查詢;由于B樹索引的有序性,使用B-樹索引可以節(jié)省SQL查詢中所需的排序操作。
- 哈希索引:哈希索引是基于哈希表的索引類型,適用于精確匹配查詢,查詢效率高,但不支持范圍查詢和排序操作。
- 空間索引:空間索引是一種用于空間數(shù)據(jù)的索引,用于處理空間數(shù)據(jù)的查詢和管理,譬如R-樹。
- 全文索引:全文索引是用于文本數(shù)據(jù)的索引類型,主要用于文本搜索和排名。
- Bitmap索引:Bitmap索引是一種特殊的索引類型,使用位圖來維護(hù)索引,適用于處理大量布爾數(shù)據(jù)的查詢。


























