5

CREATE TABLE以下两种说法有什么区别?(第一个使用KEY,第二个不使用。)

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL,
    `order_number` VARCHAR(35) NOT NULL,
    KEY `order_number` (`order_number`),
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`)
        REFERENCES `order` (`order_number`) ON DELETE CASCADE
)

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL,
    `order_number` VARCHAR(35) NOT NULL,
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`)
        REFERENCES `order` (`order_number`) ON DELETE CASCADE
)

他们都创建了有效的表。它们有什么不同,我想使用哪个?

4

1 回答 1

7

它们(几乎*)相同。

创建外键约束时,如果不存在合适的索引,则会自动在引用表的相关列上创建索引。

从外键约束的手册页:

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 标题 ...

现在您可以看到第一个版本有两个索引,但第二个版本只有一个。在第二个版本中,由外键约束自动创建的索引在添加多列索引时再次自动删除。通常这不是一个严重的问题,因为新索引使原始索引大多是多余的。

我想使用哪个?

通常,您无需担心在外键约束的引用表上显式创建索引。

但在以下情况下,您可能希望显式创建索引:

  • 您希望给它一个与约束名称不同的名称,或者
  • 当添加其他索引时,您不希望索引静默消失。
于 2012-06-24T19:46:38.740 回答