【问题标题】:Method for cascading soft deletes in parent-child relationships父子关系中级联软删除的方法
【发布时间】:2012-11-09 12:21:08
【问题描述】:

我有一个简单的架构,其中使用了软删除(这就是它的设计方式并且无法更改)。有两个表参与架构:Company (id, is_deleted)Employee (id, company_id, is_deleted) 其中company_id 当然是Company 表的FK。规则是:

  • 如果Companyis_deleted = true,那么所有引用该公司的Employee 都应该有is_deleted = true
  • Employee 可能有is_deleted = true,即使父Companyis_deleted = false

我的两个问题是 a) 如何执行这些约束? b) 当Company 被软删除时,如何最简单地确保is_deleted = true 被级联。

我添加了标签 postgresql 和 sql server,因为这些是我最感兴趣的数据库。如果其他 rdbms:es 中有其他解决方案,我也想听听。

【问题讨论】:

    标签: sql sql-server postgresql soft-delete


    【解决方案1】:

    严格来说,像这样级联值的唯一方法是使用 ON UPDATE CASCADE。要做到这一点,“is_deleted”列必须是唯一约束的一部分。

    仅此一点并不难。如果 company.id 是您的主键,那么这对列 {id, is_deleted} 也将是唯一的。该对列的唯一约束将允许您通过外键引用进行级联更新。

    但这不适用于您的情况,因为您需要允许引用值与被引用值不同

    所以在你的情况下,我认为你有三个选择。

    • 触发器
    • 存储过程
    • 应用代码

    在所有这些情况下,您都需要注意权限(可能是撤销删除权限)以及可以避免您的代码的情况。例如,dbms 命令行界面和 GUI 界面可用于绕过应用程序代码中的约束,以及根据权限在存储过程中的约束。

    【讨论】:

    • 触发器是唯一明智的前进方式。应用程序代码不能保证被调用,并且存储过程(PG 中的函数)不会通过这里的简单触发器为您购买任何东西。
    • 不确定触发器如何帮助我确保数据完整性?如果 Employee.is_deleted = false 那么 Company.is_deleted = false 也应该成立。触发器可以保证这一点吗?
    • 触发器不提供保证以与声明性约束相同的方式,但是是的,您可以编写触发器,使将 company.is_deleted 更改为 true 将执行将那家公司的 employees.is_deleted 设置为 true 的 SQL 语句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 2017-06-29
    • 2021-10-30
    • 1970-01-01
    • 2017-11-17
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多