1.8.2.3 FOREIGN KEY 约束差异
MySQL 的外键约束实现在以下关键方面与 SQL 标准不同:
-
如果父 table 中有几行具有相同的引用键值,则InnoDB会执行外键检查,就好像其他具有相同键值的父行不存在一样。例如,如果您定义
RESTRICT
类型约束,并且有一个带有多个父行的子行,则InnoDB
不允许删除任何父行。 -
如果
ON UPDATE CASCADE
或ON UPDATE SET NULL
递归更新同一个级联中先前已更新的* same table *,则其行为类似于RESTRICT
。这意味着您不能使用自引用ON UPDATE CASCADE
或ON UPDATE SET NULL
操作。这是为了防止级联更新导致无限循环。另一方面,自引用ON DELETE SET NULL
也是可能的,而自引用ON DELETE CASCADE
也是可能的。级联操作嵌套的深度不得超过 15 层。 -
在插入,删除或更新许多行的 SQL 语句中,将逐行检查外键约束(例如唯一约束)。执行外键检查时,InnoDB设置必须检查的子记录或父记录的共享行级锁。 MySQL 立即检查外键约束;该检查不会推迟到事务提交。根据 SQL 标准,默认行为应推迟检查。也就是说,仅在处理整个 SQL 语句之后检查约束。这意味着不可能使用外键删除引用自身的行。
-
没有存储引擎(包括
InnoDB
)可以识别或强制执行在引用完整性约束定义中使用的MATCH
子句。使用显式的MATCH
子句不会产生指定的效果,并且会导致ON DELETE
和ON UPDATE
子句被忽略。应避免指定MATCH
。
与参考 table 中的主键相比,SQL 标准中的MATCH
子句控制如何处理复合(多列)外键中的NULL
值。 MySQL 本质上实现了MATCH SIMPLE
定义的语义,该语义允许外键全部或部分为NULL
。在这种情况下,即使插入的(子 table)行与引用的(父)table 中的任何行都不匹配,也可以将其插入。 (可以使用触发器来实现其他语义.)
- MySQL 出于性能原因要求对引用的列进行索引。但是,MySQL 并不强制要求引用的列为
UNIQUE
或声明为NOT NULL
。
引用非UNIQUE
键的FOREIGN KEY
约束不是标准 SQL,而是InnoDBextensions。另一方面,NDB存储引擎在引用为外键的任何列上都需要显式唯一键(或主键)。
对于诸如UPDATE或DELETE CASCADE
之类的操作,未很好地定义对非唯一键或包含NULL
值的键的外键引用的处理。建议您使用仅引用UNIQUE
(包括PRIMARY
)和NOT NULL
键的外键。
- MySQL 解析但忽略“内联
REFERENCES
规范”(在 SQL 标准中定义),其中引用被定义为列规范的一部分。 MySQL 仅在作为单独的FOREIGN KEY
规范的一部分指定时才接受REFERENCES
子句。对于不支持外键的存储引擎(例如MyISAM),MySQL Server 会解析并忽略外键规范。
有关外键约束的信息,请参见第 13.1.18.5 节“外键约束”。