MySQL外键如何工作?(Innodb)

时间:2017-03-08 02:24:55

标签: mysql innodb

我在Innodb中使用MySQL外键,我想知道当我们插入子表时,Mysql如何强制执行外键约束。 Innodb似乎自动在外键列上构建索引,该功能如何在强制执行外键约束时有用? 总之,对于普通索引,我们可以创建索引文件,它使用B +树结构。外键使用什么结构?

2 个答案:

答案 0 :(得分:1)

这是一个普通的INDEX。特别是BTree。

SHOW CREATE TABLE将证明它是这样的(并且索引具有捏造的名称)。

答案 1 :(得分:1)

问:此功能[子表中的外键列上的索引]如何在强制执行外键约束时有用?

答:尝试删除父表中的行时,它很有用。或者,当尝试通过外键更新引用的列中的值时。

例如,考虑尝试删除父表中的行。外键是一个约束,它表示:如果子表中有任何行引用父表中的行,则删除操作将不会成功并将返回错误。 (我们假设为了这个例子,外键约束被声明为ON DELETE RESTRICT。)

从父项中删除行时,需要检查子表。考虑在子表上运行查询方面执行该检查,以找出:子表中是否有引用父表中的行的行。 (也就是说,它们是外键列中具有特定值的任何行吗?)

如果数据库没有强制执行约束,而我们正在对应用程序进行检查,那么我们需要运行如下的查询:

  SELECT 1
    FROM child_table
   WHERE foreign_key_col = :referenced_key_value
   LIMIT 1

该查询将受益于合适的索引,以及foreign_key_col作为前导列的索引。使用索引,MySQL可以快速消除它知道不具有该值的大量行,从而非常快地缩小到包含匹配行的块。

对于非平凡集,使用适当的索引来定位行比执行完整扫描操作更有效,检查表中的每一行,以验证没有匹配的行。

在这种情况下,理想的索引... ON child_table (foreign_key_column),...)`

除了性能优势之外,数据库还可以使用索引来阻止其他会话使用锁机制将行插入child_table(违反外键约束的行)。如果没有索引,数据库将需要锁定整个 child_table。这会破坏并发性。

(这是一个过于简化的解释。实际的机制更复杂。但这可以解释为什么外键列的索引是“有用的”。要定义外键约束,InnoDB要求定义合适的索引。如果不存在,InnoDB将创建一个。

问:外键使用什么结构?

用于表中任何其他列的相同结构,或表中任何其他索引。

FOREIGN KEY约束。关于外键约束中使用的列没有什么“特殊”。要求外键约束中使用的列必须是索引中的前导列。正如你在第一个问题的答案中所解释的那样。