postgresql - 何时对 Ecto 的“on_delete”使用“nothing”或“restrict”?
问题描述
我读过这个问题,但我不明白这部分:
这两种选择的本质区别在于 [:nothing] 允许将检查推迟到事务的后期,而 [:restrict] 则不允许。
既然我知道无论如何我都需要检查,我什么时候应该知道我是否需要推迟检查?
解决方案
这取决于您使用的数据库。
如果您使用的是 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
推荐阅读
- spring - 使用 Kotlin、SpringBoot 和 Mockk 的 POST 方法出错
- mysql - Telnet 在一个网络上工作,但在尝试在端口 3306 上连接 EC2 实例时无法在另一个网络上工作
- javascript - 多个具有不同值的不同按钮,但只使用第一个?
- api - 你如何从带有 curl 的 Flask 应用程序中获得响应?
- r - R通过带有facet_wrap和数据子集的函数调用为ggplot传递参数
- scala - 使用 Circe 解码消息时,是否可以从 DecodingFailure 中提取无效值
- bots - Discord Bot 发布频道链接
- algorithm - 找到一种时间复杂度为 O(n + k*log(k)) 的整数排序算法
- javascript - 将字符串推送到 for 循环期间创建的数组的开头和结尾
- swift - 当 self 尚未初始化时,如何在属性包装器中使用现有属性?(斯威夫特用户界面)