首页 > 解决方案 > 何时对 Ecto 的“on_delete”使用“nothing”或“restrict”?

问题描述

我读过这个问题,但我不明白这部分:

这两种选择的本质区别在于 [:nothing] 允许将检查推迟到事务的后期,而 [:restrict] 则不允许。

既然我知道无论如何我都需要检查,我什么时候应该知道我是否需要推迟检查?

标签: postgresqlelixirecto

解决方案


这取决于您使用的数据库。

如果您使用的是 MySQL,它们完全相同,因为检查总是在事务开始时完成。

NO ACTION:来自标准 SQL 的关键字。在 MySQL 中,相当于 RESTRICT。如果引用的表中存在相关的外键值,MySQL Server 将拒绝对父表的删除或更新操作。一些数据库系统有延迟检查,NO ACTION 是延迟检查。在 MySQL 中,立即检查外键约束,因此 NO ACTION 与 RESTRICT 相同。来源:https ://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html

如果我们查看 Postgres 文档,我们会发现存在差异。

限制和级联删除是两个最常见的选项。RESTRICT 防止删除引用的行。NO ACTION 表示如果在检查约束时仍然存在任何引用行,则会引发错误;如果您不指定任何内容,这是默认行为。(这两种选择之间的本质区别在于 NO ACTION 允许将检查推迟到交易的后期,而 RESTRICT 不允许。)来源:https://www.postgresql.org/docs/9.5/ddl-constraints。 html

我也很好奇为什么你可能想要选择一个而不是另一个,答案似乎是性能。看看这个邮件线程:

至于为什么您可能需要延迟检查,我能想到的唯一实际用途是删除主表中的引用行,然后在结束事务之前插入具有相同键的替换行。原则上,您可以将其作为单个 UPDATE 执行,但可能是您的应用程序逻辑使其难以执行。来源:https ://www.postgresql.org/message-id/4271.1233022978%40sss.pgh.pa.us


推荐阅读