它们(几乎*)相同。
创建外键约束时,如果不存在合适的索引,则会自动在引用表的相关列上创建索引。
从外键约束的手册页:
InnoDB 需要外键和引用键上的索引,以便外键检查可以快速且不需要表扫描。在引用表中,必须有一个索引,其中外键列按相同顺序列为第一列。如果引用表不存在,则会在引用表上自动创建此类索引。如果您创建另一个可用于强制外键约束的索引,则此索引可能会在稍后被静默删除。index_name,如果给定,如前所述使用。
强调我的。
(*) 我说的几乎一样,因为有一些细微的差别。
索引名称
在第一个版本中,您为索引指定了一个明确的名称,但在第二个版本中,索引的名称与约束的名称相同(如果已指定)。
比较SHOW INDEX
两种情况下的输出:
版本 1:
Table Non_unique Key_name Seq_in_index Column_name ...
标题 1 order_number 1 order_number ...
版本 2:
Table Non_unique Key_name Seq_in_index Column_name ...
标题 1 order_number_fk 1 order_number ...
如您所见,这里唯一的区别是索引的名称。
无声滴
另一个微妙的区别是,在第二种情况下,正如文档所述,添加新索引时自动创建的索引可能会被静默删除:
如果您创建另一个可用于强制外键约束的索引,则此索引可能会在稍后被静默删除。
这意味着,如果您稍后在以下位置创建多列索引,例如(order_number, title)
:
CREATE INDEX ix_order_number_title ON title (order_number, title);
然后SHOW INDEX
再次运行:
版本 1:
Table Non_unique Key_name Seq_in_index Column_name ...
标题 1 order_number 1 order_number ...
标题 1 ix_order_number_title 1 订单号 ...
标题 1 ix_order_number_title 2 标题 ...
版本 2:
Table Non_unique Key_name Seq_in_index Column_name ...
标题 1 ix_order_number_title 1 订单号 ...
标题 1 ix_order_number_title 2 标题 ...
现在您可以看到第一个版本有两个索引,但第二个版本只有一个。在第二个版本中,由外键约束自动创建的索引在添加多列索引时再次自动删除。通常这不是一个严重的问题,因为新索引使原始索引大多是多余的。
我想使用哪个?
通常,您无需担心在外键约束的引用表上显式创建索引。
但在以下情况下,您可能希望显式创建索引:
- 您希望给它一个与约束名称不同的名称,或者
- 当添加其他索引时,您不希望索引静默消失。