![](/img/trans.png)
[英]MySQL - Foreign Key does not work even when InnoDB is on (Ubuntu 16.04)(Error code: 1215)
[英]How does MySQL foreign key work?(Innodb)
我在Innodb中使用MySQL外键,我想知道当我们插入子表时Mysql如何执行外键约束。 Innodb似乎自动在外键列上建立索引,此功能对强制执行外键约束有什么用? 总之,对于普通索引,我们可以创建使用B +树结构的索引文件。 外键使用什么结构?
这是一个普通的INDEX
。 特别是BTree。
SHOW CREATE TABLE
将证明它是这样的(并且具有索引的虚构名称)。
问:此功能[子表中外键列上的索引]对强制执行外键约束有什么用?
答:尝试删除父表中的行时很有用。 或尝试更新外键引用的列中的值时。
例如,考虑尝试删除父表中的行。 外键是一个约束条件,它表示:如果子表中有任何行引用父表中的行,则删除操作将不会成功,并且将返回错误。 (为便于说明,我们假设外键约束声明为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
是一个约束 。 对于在外键约束中使用的列,没有任何“特殊”之处。 要求外键约束中使用的列必须是索引中的前导列。 如您对第一个问题的回答中所述。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.