我了解什么是外键,并且在对我设计的所有数据库表有意义的地方都包含它们。
然而,一直让我困惑的是我是否应该明确设置“更新时”和“删除时”功能(缺乏更好的术语)。例子:
CREATE TABLE "test1"
(
id serial,
referenceid integer,
FOREIGN KEY (referenceid) REFERENCES "othertable" (id) ON UPDATE CASCADE ON DELETE CASCADE
)
Run Code Online (Sandbox Code Playgroud)
此代码特意显式添加了技术上“不必要”的部分:“ON UPDATE CASCADE ON DELETE CASCADE”。
既然这不是默认执行的,那么一定有一个原因!毕竟,默认行为始终(或至少应该始终是)最常用的行为:
CREATE TABLE "test2"
(
id serial,
referenceid integer,
FOREIGN KEY (referenceid) REFERENCES "othertable" (id)
)
Run Code Online (Sandbox Code Playgroud)
在 test1 表中,据我了解,如果“othertable”更改“id”列值或删除任何记录,则意味着 test1 表中引用的记录将被更新或删除。从表面上看,这似乎应该是默认行为。
在 test2 表中,再次据我了解,如果“othertable”更改“id”列值,或删除任何记录,这意味着如果 test2 中有记录,PostgreSQL 将拒绝执行查询参考正在修改的内容。
我基本上对“更新时”和“删除时”的整个概念感到困惑。为什么有人希望这样的查询被拒绝呢?而且“CASCADE”甚至不是唯一的选择(除了没有);您可以使用多个其他值来导致各种行为(我不明白)。
由于表之间存在规定的关系(通过外键),因此您希望它们保持一致难道不是重点吗?那么,如果“主”表发生更改,为什么您不希望它“级联”呢?
这可能类似于我永远无法理解为什么面向对象编程在代码中具有“安全措施”,使您无法直接更改或检索对象的属性并被迫通过“getters”和“setters”。我的意思是,如果某些东西可以在您的数据库中执行查询,那么不是“全部丢失”了吗?他们可以这样做:
DELETE FROM table1/table2 CASCADE
Run Code Online (Sandbox Code Playgroud)
... 或类似的东西。
ON UPDATE/ON DELETE 机制似乎几乎就像数据库工程师无法决定最佳行为,而是将其交给产品的用户。对我来说,这增加了很多困惑和焦虑。 …
postgresql ×1