MySQL的外键约束实现在以下关键方面与SQL标准不同:
-
如果父表中有几行具有相同的引用键值,则
InnoDB
执行外键检查,就像其他具有相同键值的父行不存在一样。例如,如果定义RESTRICT
类型约束,并且子行中有多个父行,InnoDB
则不允许删除任何父行。 -
如果
ON UPDATE CASCADE
或ON UPDATE SET NULL
递归更新 同一级联中先前更新过的同一张表,则其行为类似于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
应避免指定。MATCH
SQL标准中 的子句控制NULL
与引用表中的主键进行比较时如何处理复合(多列)外键中的值。MySQL本质上实现了定义的语义MATCH SIMPLE
,该语义 允许外键全部或部分NULL
。在这种情况下,即使插入的(子表)行与引用的(父)表中的任何行都不匹配,也可以将其插入。(可以使用触发器来实现其他语义。) -
MySQL出于性能原因要求对引用的列进行索引。但是,MySQL没有强制要求
UNIQUE
必须声明或声明所引用的列NOT NULL
。一个
FOREIGN KEY
引用了非约束UNIQUE
关键不是标准的SQL,而是一个InnoDB
扩展。的NDB
存储引擎,在另一方面,要求在作为外键引用的任何列的显式唯一密钥(或主键)。NULL
对于诸如UPDATE
或的操作,未很好地定义对 非唯一键或包含值的 键的外键引用的处理DELETE CASCADE
。建议您使用仅引用UNIQUE
(包括PRIMARY
)和NOT NULL
键的外键。 -
MySQL解析但忽略“ 内联
REFERENCES
规范 ”(在SQL标准中定义),其中引用被定义为列规范的一部分。MySQLREFERENCES
仅在作为单独FOREIGN KEY
规范的一部分指定时才接受 子句。对于不支持外键的存储引擎(例如MyISAM
),MySQL Server会解析并忽略外键规范。
有关外键约束的信息,请参见 第13.1.20.5节“外键约束”。