我有一个感兴趣的问题:
我在mysql中有两个表InnoDb
表tbl_a
有一个主键,名为a_id
;
表格tbl_b
在b_id
上有tbl_a.a_id
个主ON DELETE NO ACTION
和外键。
+-------------+---------------+---------------+
| Table Name | Primary Key | Foreign Key |
+-------------+---------------+---------------+
| tbl_a | a_id | |
| tbl_b | b_id | a_id |
+-------------+---------------+---------------+
为什么我仍然会使用InnoDb和外键,如果我到底没有真正使用外键的魔力呢?
还有一点使用
innodb和外键
而不是
myisam,没有外键
如果我只是删除或更新“NO ACTION
”?
我希望你得到我的兴趣:)
答案 0 :(得分:56)
我认为你误解了ON DELETE NO ACTION
的含义。它不意味着抑制外键约束。
当您删除外键引用的记录时,InnoDB可以采取自动操作来纠正这种情况:
CASCADE
,意思是删除引用记录。 (这对user_address.user_id
这样的事情有意义。如果你硬删除用户,你可能也想硬删除所有用户的地址。)SET NULL
,意思是,清除引用键。 (这可能对file.last_modified_by
之类的内容有意义。如果你硬删除用户,你可能希望文件的last-modified-by变得简单地“未知”。)如果指定NO ACTION
,则告诉InnoDB您不希望它采取这些操作。因此InnoDB无法为您解决问题;它只能拒绝DELETE
并返回错误。
因此,ON DELETE NO ACTION
实际上与ON DELETE RESTRICT
(默认值)相同。
(注意:在某些DBMS中,在标准SQL中,ON DELETE NO ACTION
与ON DELETE RESTRICT
略有不同:在ON DELETE NO ACTION
中,DELETE
表示“接受ON DELETE NO ACTION
内的ON DELETE RESTRICT
当前事务,但如果我在纠正问题之前尝试提交它,则拒绝整个事务“。但InnoDB不支持延迟检查,因此它将DELETE
与{{1}}完全相同,并始终拒绝{{1}} 立即。)
请参阅MySQL 5.6参考手册中的§§14.2.2.5 "FOREIGN KEY Constraints"和13.1.17.2 "Using FOREIGN KEY Constraints"。
答案 1 :(得分:9)
即使没有ON DELETE / UPDATE CASCADE
,外键约束也可确保在子表中插入一个值时,它在父表中具有正确匹配的值(如果FK列为,则为NULL
可为空)。尝试在子表的FK列中插入无效值会在约束失败时导致错误,因此您的数据完整性受到保护。
错误1452(23000):无法添加或更新子行:外键约束失败
定义外键约束还隐式定义子表中FK列的索引,虽然您可以手动定义索引,但会提高连接性能。
ON DELETE NO ACTION
(与省略ON DELETE
子句相同)将主动阻止删除父行,如果它被任何子表引用,而不是被动地允许它将被删除而不会影响子行。