【问题标题】:Are composite unique keys indexed in MySQL?复合唯一键是否在 MySQL 中建立索引?
【发布时间】:2020-02-03 11:09:49
【问题描述】:

我有一个 UserSkills 表,其中包含三列:id (PK)userId (FK)skillId (FK)

我想对 userIdskillId 的组合实施复合唯一约束。为了更快地查找,我希望在 (userId, skillId) 上建立复合索引。

据我所知,MySQL 会自动索引唯一列。但是,到目前为止,我看到的所有示例和我自己的实现都涉及单列唯一约束。我想知道 MySQL 是否也索引复合唯一键。如果是,是否将其视为普通的多列索引?

对于普通的多列索引,根据MySQL参考手册:

如果表有一个多列索引,任何最左边的前缀 优化器可以使用索引来查找行。例如,如果 您在 (col1, col2, col3) 上有一个三列索引,您已编制索引 (col1)、(col1, col2) 和 (col1, col2, col3) 的搜索功能。

简而言之,我想知道是否应该在声明上述涉及它们的多列唯一约束之后创建一个 (userId, SkillId) 的多列索引,或者这只是多余的,因此不需要?

【问题讨论】:

  • 只需在两个字段上添加唯一索引即可。 CREATE UNIQUE INDEX index_name ON table_name(index_column_1,index_column_2,...);

标签: mysql database unique-index


【解决方案1】:

所以对于你的领域,id (PK)、userId (FK) 和 skillId (FK), mysql 会自动在(id)(唯一)上创建索引,在(userId)(非唯一)和(skillId)(非唯一)上创建索引。

您仍然需要在 (userId, skillId) 上添加一个唯一索引。

这可以替换(userId) 上的非唯一索引,因为优化器可以在需要通过userId 查找时使用(userId, skillId) 索引。但是,当索引被 mysql 中的外键使用时创建和删除索引可能很麻烦,因此您可能只想添加复合唯一索引。

【讨论】:

  • 所以,基本上你建议不要在 (userId, skillId) 上创建复合唯一约束和另一个复合索引,我最好将两者结合起来并在 @987654332 上创建唯一索引@。我对吗?如果是,这将确保组合的唯一性并将它们索引以及按照正常的复合索引,这将是我正在寻找的完美解决方案。
  • 我会说是的。 RDBMS 中的唯一性约束只是创建一个唯一索引。为此,您只需执行一次。
【解决方案2】:

问:want to know if MySQL indexes composite unique keys as well. And if it does, is it treated as a normal multi-column index or not

是的,请参阅:

MySQL 要求对外键列进行索引;如果您创建一个具有外键约束但在给定列上没有索引的表,则会创建一个索引。例外:NDB Cluster 需要外键列上的显式唯一键(或主键)。

https://dev.mysql.com/doc/refman/5.6/en/constraint-foreign-key.html

FloridaDBA 评论:

Just add a unique index on the two fields. CREATE UNIQUE INDEX index_name ON table_name(index_column_1,index_column_2,...)

这是可能的,但我不建议“仅仅”这样做,因为就像手册中所说的那样。

优化器可以使用索引的任何最左前缀来查找行

这取决于您的查询是如何构建的以及您如何实现索引,但是否有可能会看到性能下降,因为它不能总是使用复合索引。

要了解复合索引是否是一个好主意,您必须研究所有使用这些表的查询,并检查诸如WHERE 子句之类的内容如何使用这些列。重构其他查询(如果有)可能有助于优化组合键的使用。

有关此内容的更多信息,请阅读本文并研究给定的示例。

https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html

【讨论】:

  • 在多个列上创建唯一索引对某些情况有利而对其他情况不利,这是正确的。但是我有涉及userIdskillId 的特定查询,因此复合索引是有意义的。我还想澄清我的概念,以及 MySQL 在像这样的更多内在情况下的行为。
猜你喜欢
  • 2010-11-07
  • 1970-01-01
  • 2015-11-09
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 2018-07-29
  • 2015-08-10
相关资源
最近更新 更多