索引、單列索引、複合索引、主鍵、唯一索引、聚簇索引、非聚簇索引、唯一聚簇索引 的區別與聯繫

B樹與紅黑樹最廣泛的應用就是數據庫索引,熟練使用索引是程序員最重要的基本功之一。索引的數據結構可以是樹,也可以是哈希表。常用的數據庫都是樹結構的索引,本篇的背景也全部以樹結構的索引爲前提。本文旨在梳理各種常見的索引類型,簡明扼要地說明它們的區別與聯繫,不討論數據結構與算法。話不多說,直接上乾貨。

索引

數據庫只做兩件事情:存儲數據、檢索數據。而索引是在你存儲的數據之外,額外保存一些路標(一般是B+樹),以減少檢索數據的時間。所以索引是主數據衍生的附加結構。

一張表可以建立任意多個索引,每個索引可以是任意多個字段的組合。索引可能會提高查詢速度(如果查詢時使用了索引),但一定會減慢寫入速度,因爲每次寫入時都需要更新索引,所以索引只應該加在經常需要搜索的列上,不要加在寫多讀少的列上。

單列索引 與 複合索引

只包含一個字段的索引叫做單列索引,包含兩個或以上字段的索引叫做複合索引(或組合索引)。建立複合索引時,字段的順序極其重要。

下面這個SQL語句在 列X,列Y,列Z 上建立了一個複合索引。

CREATE INDEX 索引名 ON 表名(列名X, 列名Y, 列名Z);
其實這相當於建立了三個索引,分別是:

1、單列索引(列X) 2、複合索引(列X, 列Y) 3、複合索引(列X,列Y,列Z)。

如何理解呢?

我們可以把多個字段組合的索引比喻成一個老式的紙質電話簿,三列分別是:

姓 - 名 - 電話號碼

電話簿中的內容先按照姓氏的拼音排序,相同姓氏再按名字的拼音排序,這相當於在(姓,名)上建立了一個複合索引。你可以通過這個索引快速找到所有具有特定姓氏的人的電話號碼,也可以快速找到具有特定 姓-名 組合的人的電話號碼。然而,想象一下,如果你想找到某個特定名字的人,其實這個索引是沒有用的,你只能從頭到尾遍歷整個電話簿。

唯一索引 與 主鍵

唯一索引是在表上一個或者多個字段組合建立的索引,這個(或這幾個)字段的值組合起來在表中不可以重複。一張表可以建立任意多個唯一索引,但一般只建立一個。

主鍵是一種特殊的唯一索引,區別在於,唯一索引列允許null值,而主鍵列不允許爲null值。一張表最多建立一個主鍵,也可以不建立主鍵。

聚簇索引、非聚簇索引、主鍵

在《數據庫原理》一書中是這麼解釋聚簇索引和非聚簇索引的區別的:

聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。

怎麼理解呢?

聚簇索引的順序,就是數據在硬盤上的物理順序。一般情況下主鍵就是默認的聚簇索引。

一張表只允許存在一個聚簇索引,因爲真實數據的物理順序只能有一種。如果一張表上還沒有聚簇索引,爲它新創建聚簇索引時,就需要對已有數據重新進行排序,所以對錶進行修改速度較慢是聚簇索引的缺點,對於經常更新的列不宜建立聚簇索引。

聚簇索引性能最好,因爲一旦具有第一個索引值的記錄被找到,具有連續索引值的記錄也一定物理地緊跟其後。一張表只能有一個聚簇索引,所以非常珍貴,必須慎重設置,一般要根據這個表最常用的SQL查詢方式選擇某個(或多個)字段作爲聚簇索引(或複合聚簇索引)。

聚簇索引默認是主鍵,如果表中沒有定義主鍵,InnoDB[1]會選擇一個唯一的非空索引代替(“唯一的非空索引”是指列不能出現null值的唯一索引,跟主鍵性質一樣)。如果沒有這樣的索引,InnoDB會隱式地定義一個主鍵來作爲聚簇索引。

聚簇索引 與 唯一索引

嚴格來說,聚簇索引不一定是唯一索引,聚簇索引的索引值並不要求是唯一的,唯一聚簇索引纔是!在一個有聚簇索引的列上是可以插入兩個或多個相同值的,這些相同值在硬盤上的物理排序與聚簇索引的排序相同,僅此而已

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