Mysql
添加主鍵預設集群索引以外的集群索引
create table t1 (id int primary key auto_increment, name varchar(20))
上表中
id
是主鍵,預設情況下將群索引添加到主鍵列。我的問題是,我們也可以在列(名稱)上添加集群索引嗎??
我們也可以在列(名稱)上添加集群索引嗎?
不,只有一個索引是聚集的。
對於 MySQL:
- 如果主鍵存在,則它是集群的。
- 如果不存在主索引但存在唯一索引,則聚集第一個唯一索引。
- 如果不存在唯一索引,則按內部記錄號(隱藏、不可訪問)的索引是聚群的。
案例是什麼?正常化?那是一個有 2 列的表,一個“名稱”和一個“ID”嗎?那麼這是最佳模式:
CREATE TABLE Names ( id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(44) NOT NULL, PRIMARY KEY(id), UNIQUE(name) ) ENGINE=InnoDB;
這有效地為您提供了兩個 BTree,每個 BTree 都包含兩列,並且每個都被限制為具有其中一列 be
UNIQUE
。換句話說,一個提供從 id 到 name 的最佳查找;另一個以另一種方式提供最佳查找。可以玩語義遊戲並說它
UNIQUE(name)
提供了第二個“聚集”索引,因為id
它隱式包含在該 BTree 中。不要專注於“集群”這個詞;讓我們深入到實現中,看看它是否給了你真正想要的東西,即“效率”。
專注於您使用的索引的效率是(或不是)。這樣做時,將非常有效地使用
SELECT name FROM Names WHERE id = 123
由創建的 BTree——向下鑽取樹以在葉節點中定位“123”。PRIMARY KEY``name
類似地,將使用
SELECT id FROM Names WHERE name = 'Smith'
由創建的 BTree 。UNIQUE(name)
由於 PK 隱含在 InnoDB 二級索引中;這實際上是一個 BTree(name, id)
(加上一個唯一性約束name
)。同樣,查找將是對 BTree 的非常有效的向下鑽取,落在包含 pair 的葉節點中的行上(name, id)
。出於所有實際目的,
Names
有兩個“聚集索引”。但是,在了解 BTree 的工作原理以及 BTree對這些查詢的工作效率之後,我們避免使用“集群”這個詞並專注於性能。