Mysql 如果其中一个字段已经是唯一的,是否可以添加复合唯一键

Mysql 如果其中一个字段已经是唯一的,是否可以添加复合唯一键,mysql,schema,unique-constraint,unique-key,unique-index,Mysql,Schema,Unique Constraint,Unique Key,Unique Index,在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`

在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\u-classification\u-id
)上添加一个唯一键(其中一个字段(
sku
)上已经有唯一索引)是否是多余的?或者它不是,而且确实有这样重复的唯一索引的某些原因?

是的,您可以。但这毫无意义。但是,让我们分析一下发生了什么

索引
唯一
或不唯一)是一个便于在表中查找的BTree

UNIQUE
索引既是一个索引,也是一个“约束”,表示不应存在任何重复项

您已经说过
唯一(sku)
。这提供了索引和唯一性约束

按该顺序添加
UNIQUE(sku,x)

  • 不提供任何附加的唯一性约束
  • 不提供任何额外的索引功能,除了
  • 如果
    SELECT
    中提到的两列仅为
    sku
    x
    ,则提供了一个“覆盖”索引。即使如此,您也可以将其作为
    索引
    而不是
    唯一索引
    ,因为
  • 每次插入
    都必须做一些额外的工作来防止“重复密钥”。(好的,
    插入
    代码不够智能,无法看到您有
    唯一(sku)
如果这是您的完整表,则没有充分的理由让
id自动递增
;您还可以将
sku
提升为
主键
。(主键是一个
唯一键

此外。。。另一方面,如果您建议
UNIQUE(x,sku)
,则有一点不同。这为您提供了一种通过
x
进行高效查找的方法—范围为
x
,或
x=常量和介于…
之间的sku,或
(sku,x)
未提供的某些其他内容。索引中的顺序很重要。但是,同样,它也可以是
索引(x,sku)
,而不是
唯一的

因此,表的最佳索引集不是3个索引,而是1个:

PRIMARY KEY(sku)

还有一个注意事项:对于InnoDB,PK与数据一起“聚集”在BTree中。也就是说,通过PK查找是非常有效的。当您需要浏览“二级索引”时,有两个步骤:首先向下钻取二级索引的BTree以查找PK,然后向下钻取PK的BTree。

首先为什么要这样做?@juergen-d遗留代码。正在考虑是否应该删除它。第一个唯一密钥本身将允许多个具有不同分类的相同sku。第二种方法会阻止多行使用相同的sku,因此它会使第一行不相关。真正的问题是真正需要什么。是否可以使用不同分类的相同sku,或者只能有一行使用特定sku。您看,理想的业务逻辑是什么?@sloancher sku应该是唯一的。所以我猜复合密钥没有任何区别,应该删除。是的。它永远不会起作用,因为一个sku只允许有一行。