什么时候使用 "nothing" 或 "restrict" 作为 "on_delete" 与 Ecto?

When to use "nothing" or "restrict" for "on_delete" with Ecto?

我读过这个但是我不明白这部分:

the essential difference between these two choices is that [:nothing] allows the check to be deferred until later in the transaction, whereas [:restrict] does not.

我什么时候知道我需要推迟检查,因为我知道我无论如何都需要检查?

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

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

NO ACTION: A keyword from standard SQL. In MySQL, equivalent to RESTRICT. The MySQL Server rejects the delete or update operation for the parent table if there is a related foreign key value in the referenced table. Some database systems have deferred checks, and NO ACTION is a deferred check. In MySQL, foreign key constraints are checked immediately, so NO ACTION is the same as RESTRICT. Source: https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html

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

Restricting and cascading deletes are the two most common options. RESTRICT prevents deletion of a referenced row. NO ACTION means that if any referencing rows still exist when the constraint is checked, an error is raised; this is the default behavior if you do not specify anything. (The essential difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction, whereas RESTRICT does not.) Source: https://www.postgresql.org/docs/9.5/ddl-constraints.html

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

As for why you might want a deferred check, the only practical use I can think of is to delete a referenced row in the master table, then insert a replacement row with the same key, before ending the transaction. In principle you could do that as a single UPDATE, but it might be that your application logic makes it awkward to do so. Source: https://www.postgresql.org/message-id/4271.1233022978%40sss.pgh.pa.us