小编pgp*_*ant的帖子

对外键使用“ON UPDATE CASCADE ON DELETE CASCADE”是好还是坏主意?为什么这个机制会存在呢?

我了解什么是外键,并且在对我设计的所有数据库表有意义的地方都包含它们。

然而,一直让我困惑的是我是否应该明确设置“更新时”和“删除时”功能(缺乏更好的术语)。例子:

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

12
推荐指数
2
解决办法
2万
查看次数

标签 统计

postgresql ×1