在 MySQL 中,下面的语句是否有意义?
CREATE TABLE `sku_classification` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sku` int(10) unsigned NOT NULL,
`business_classification_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `IDX_SKU_BUSINESS_CLASSIFICATION` (`sku`,`business_classification_id`),
UNIQUE KEY `sku` (`sku`)
)
在字段组合(sku
、business_classification_id
)上添加唯一键是否不必要,其中之一(sku
) ) 已经有唯一索引了吗?还是不是,这种重复的唯一索引确实有某种原因?
最佳答案
是的,你可以。但这没有意义。但是,让我们分析一下这是怎么回事。
INDEX
(UNIQUE
或不)是一个有助于在表中查找的 BTree。
UNIQUE
索引既是索引又是“约束”,表示不得有任何重复项。
您已经说过 UNIQUE(sku)
。这提供了索引和唯一性约束。
添加 UNIQUE(sku, x)
按此顺序:
- 不提供任何额外的唯一性约束,
- 不提供任何额外的索引功能,except...
- 是否提供了一个可能有用的“覆盖”索引如果
SELECT
中提到的唯一两列是sku
和x
。即便如此,您也可以将其设为INDEX
而不是UNIQUE
,因为... - 每个
INSERT
都必须做一些额外的努力来防止“重复键”。 (好的,INSERT
代码不够智能,无法看到您有UNIQUE(sku)
。)
如果那是您的完整表格,没有充分的理由让 id AUTO_INCREMENT
;您也可以将 sku
提升为 PRIMARY KEY
。 (PK 是一个 UNIQUE KEY
。)
此外...如果,另一方面,您建议 UNIQUE(x, sku)
,那么就会有一个细微的差别。这为您提供了一种通过 x
进行高效查找的方法——一系列 x
,或 x=constant AND sku BETWEEN ...
,或(sku, x)
未提供的某些其他内容。 索引中的顺序很重要。但是,同样,它也可能是 INDEX(x, sku)
,而不是 UNIQUE
。
因此,呈现的表的最佳索引集不是 3 个索引,而是 1 个:
PRIMARY KEY(sku)
还有一点要注意:使用 InnoDB,PK 与数据一起“聚集”在 BTree 中。即按PK查找效率很高。当需要遍历“二级索引”时,有两个步骤:首先向下钻取二级索引的 BTree 找到 PK,然后向下钻取 PK 的 BTree。
关于mysql - 如果其中一个字段已经是唯一的,我可以添加一个复合唯一键吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43530523/