【问题标题】:How do the Postgres foreign key 'on update' and 'on delete' options work?Postgres 外键“更新时”和“删除时”选项如何工作?
【发布时间】:2010-09-18 13:26:41
【问题描述】:

谁能提供一个清晰的解释/例子来说明这些函数的作用,以及何时适合使用它们?

【问题讨论】:

    标签: sql database-design postgresql foreign-keys cascade


    【解决方案1】:

    直接来自the manual...

    我们知道外键不允许创建与任何产品无关的订单。但是,如果在创建引用该产品的订单后删除该产品怎么办? SQL 也允许您处理它。直观地说,我们有几个选择:

    不允许删除引用的产品

    同时删除订单

    还有什么?

    CREATE TABLE order_items (
     product_no integer REFERENCES products ON DELETE RESTRICT,
     order_id integer REFERENCES orders ON DELETE CASCADE,
     quantity integer,
     PRIMARY KEY (product_no, order_id)
    );
    

    限制和级联删除是两个最常见的选项。 RESTRICT 防止删除引用的行。 NO ACTION 表示如果在检查约束时仍然存在任何引用行,则会引发错误;如果您不指定任何内容,这是默认行为。 (这两种选择之间的本质区别在于 NO ACTION 允许将检查推迟到事务的后期,而 RESTRICT 不允许。) CASCADE 指定当一个引用的行被删除时,引用它的行应该被自动删除也是。还有两个其他选项:SET NULL 和 SET DEFAULT。当引用的行被删除时,这些会导致引用列分别设置为空值或默认值。请注意,这些并不能成为您遵守任何约束的借口。例如,如果某个操作指定了 SET DEFAULT,但默认值不满足外键,则操作将失败。

    与 ON DELETE 类似,还有一个 ON UPDATE,它在引用的列被更改(更新)时被调用。可能的操作是相同的。

    编辑:您可能想看看这个相关问题:When/Why to use Cascading in SQL Server?。问题/答案背后的概念是相同的。

    【讨论】:

      【解决方案2】:

      我有一个 PostGreSQL 数据库,当我有一个从数据库中删除的用户并且我需要从其他表中删除它的信息时,我使用 On Delete。这种方式我只需要执行 1 次删除操作,具有 ON 删除功能的 FK 将从其他表中删除信息。

      您可以对 ON Update 执行相同的操作。如果您更新表并且该字段具有 On Update 的 FK,如果在 FK 上进行了更改,您将在 FK 表上注意到。

      【讨论】:

        【解决方案3】:

        Daok 说的是真的……它可以相当方便。另一方面,让数据库中的事情自动发生可能是一个真正的问题,尤其是在消除数据时。将来有人可能会指望 FK 通常会在有孩子时阻止删除父母这一事实,而没有意识到您使用 On Delete Cascade 不仅不能阻止删除,它还​​会在几十个中生成大量数据由于级联删除的瀑布,其他表消失了。

        @Arthur 的评论。

        数据库中“隐藏”的事情发生得越频繁,任何人就越不可能很好地掌握正在发生的事情。触发器(这本质上是一个触发器)可以导致我删除一行的简单操作,在整个数据库中产生广泛的后果。我发出一条 Delete 语句,17 个表受到级联触发器和约束的影响,而对于命令的发出者来说,这一切都不是显而易见的。 OTOH,如果我将删除父项及其所有子项放在一个过程中,那么任何人都可以非常容易和清楚地看到当我发出命令时会发生什么。

        这与我设计数据库的好坏完全无关。它与触发器引入的操作问题有关。

        【讨论】:

        • 如果架构设计正确,我认为这不是问题。通常,如果没有父数据,数据的子数据 (FK) 并没有真正的用处。
        • 这是一个合理的说法。但是,无意识发生的事情越多,数据库就越不成功。请参阅上面答案中的编辑。
        • 您必须决定数据库是否只是应用程序的数据转储,或者数据库本身是否具有价值/意义。当一个数据库可以在没有应用程序的情况下运行时——直接数据加载、直接查询访问等——你必须在数据库层定义规则,因为应用程序不是为你做这些事情的。以我的经验,初级开发人员倾向于将数据库视为由应用程序控制,而高级开发人员(被烧死太多次)将数据库设计为独立存在。请记住,在应用程序消失后,数据库仍然可以存在很长时间。这只是封装原理,应用于数据库。
        【解决方案4】:

        不用编写方法来完成级联删除或级联更新的所有工作,您可以简单地编写一条警告消息。比重新发明轮子要容易得多,而且它让客户(以及新开发人员拿起代码)一目了然

        【讨论】:

          猜你喜欢
          • 2017-03-03
          • 1970-01-01
          • 2019-10-24
          • 1970-01-01
          • 2018-05-26
          • 2020-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多