1.8.2.3 FOREIGN KEY 约束差异

MySQL 的外键约束实现在以下关键方面与 SQL 标准不同:

  • 如果父 table 中有几行具有相同的引用键值,则InnoDB会执行外键检查,就好像其他具有相同键值的父行不存在一样。例如,如果您定义RESTRICT类型约束,并且有一个带有多个父行的子行,则InnoDB不允许删除任何父行。

  • 如果ON UPDATE CASCADEON UPDATE SET NULL递归更新同一个级联中先前已更新的* same table *,则其行为类似于RESTRICT。这意味着您不能使用自引用ON UPDATE CASCADEON UPDATE SET NULL操作。这是为了防止级联更新导致无限循环。另一方面,自引用ON DELETE SET NULL也是可能的,而自引用ON DELETE CASCADE也是可能的。级联操作嵌套的深度不得超过 15 层。

  • 在插入,删除或更新许多行的 SQL 语句中,将逐行检查外键约束(例如唯一约束)。执行外键检查时,InnoDB设置必须检查的子记录或父记录的共享行级锁。 MySQL 立即检查外键约束;该检查不会推迟到事务提交。根据 SQL 标准,默认行为应推迟检查。也就是说,仅在处理整个 SQL 语句之后检查约束。这意味着不可能使用外键删除引用自身的行。

  • 没有存储引擎(包括InnoDB)可以识别或强制执行在引用完整性约束定义中使用的MATCH子句。使用显式的MATCH子句不会产生指定的效果,并且会导致ON DELETEON UPDATE子句被忽略。应避免指定MATCH

与参考 table 中的主键相比,SQL 标准中的MATCH子句控制如何处理复合(多列)外键中的NULL值。 MySQL 本质上实现了MATCH SIMPLE定义的语义,该语义允许外键全部或部分为NULL。在这种情况下,即使插入的(子 table)行与引用的(父)table 中的任何行都不匹配,也可以将其插入。 (可以使用触发器来实现其他语义.)

  • MySQL 出于性能原因要求对引用的列进行索引。但是,MySQL 并不强制要求引用的列为UNIQUE或声明为NOT NULL

引用非UNIQUE键的FOREIGN KEY约束不是标准 SQL,而是InnoDBextensions。另一方面,NDB存储引擎在引用为外键的任何列上都需要显式唯一键(或主键)。

对于诸如UPDATEDELETE CASCADE之类的操作,未很好地定义对非唯一键或包含NULL值的键的外键引用的处理。建议您使用仅引用UNIQUE(包括PRIMARY)和NOT NULL键的外键。

  • MySQL 解析但忽略“内联REFERENCES规范”(在 SQL 标准中定义),其中引用被定义为列规范的一部分。 MySQL 仅在作为单独的FOREIGN KEY规范的一部分指定时才接受REFERENCES子句。对于不支持外键的存储引擎(例如MyISAM),MySQL Server 会解析并忽略外键规范。

有关外键约束的信息,请参见第 13.1.18.5 节“外键约束”