索引
數據庫只做兩件事情:存儲數據、檢索數據。而索引是在你存儲的數據之外,額外保存一些路標(一般是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會隱式地定義一個主鍵來作為聚簇索引。
聚簇索引 與 唯一索引
嚴格來說,聚簇索引不一定是唯一索引,聚簇索引的索引值並不要求是唯一的,唯一聚簇索引才是!在一個有聚簇索引的列上是可以插入兩個或多個相同值的,這些相同值在硬盤上的物理排序與聚簇索引的排序相同,僅此而已。