Sql 在父子关系中级联软删除的方法
我有一个简单的模式,其中使用了软删除(这就是它的设计方式,不能更改)。模式中有两个表:Sql 在父子关系中级联软删除的方法,sql,sql-server,postgresql,soft-delete,Sql,Sql Server,Postgresql,Soft Delete,我有一个简单的模式,其中使用了软删除(这就是它的设计方式,不能更改)。模式中有两个表:Company(id,is\u deleted)和Employee(id,Company\u id,is\u deleted)其中Company\u id当然是Company表的FK。这些规则是: 如果公司有被删除=真,那么所有提及该公司的员工都应该有被删除=真 但是一名员工可能有被删除=真,即使母公司公司有被删除=假 我的两个问题是a)如何实施这些约束?b) 当软删除公司时,如何确保将删除=真级联 我添加
Company(id,is\u deleted)
和Employee(id,Company\u id,is\u deleted)
其中Company\u id
当然是Company
表的FK。这些规则是:
- 如果
有公司
,那么所有提及该公司的被删除=真
都应该有员工
被删除=真
- 但是一名
可能有员工
,即使母公司被删除=真
有公司
被删除=假
公司
时,如何确保将删除=真
级联
我添加了标记postgresql和sql server,因为这些是我最感兴趣的数据库。如果在其他rdbms中还有其他解决方案,我也想听听。严格地说,像这样级联值的唯一方法是使用更新级联。为此,列“is_deleted”必须是唯一约束的一部分 这一点并不难。如果company.id是主键,那么{id,is_deleted}列对也将是唯一的。这对列上的唯一约束将允许您通过外键引用级联更新 但这在您的情况下不起作用,因为您需要允许引用值与引用值不同 所以在你的情况下,我认为你有三个选择
- 触发
- 存储过程
- 应用程序代码
在所有这些情况下,您都需要注意权限(可能会取消删除权限)和可以避免使用代码的情况。例如,dbms命令行界面和GUI界面可用于绕过应用程序代码中的约束,并根据权限绕过存储过程中的约束。触发器是唯一可行的方法。应用程序代码不能保证被调用,存储过程(PG中的函数)也不能通过简单的触发器为您购买任何东西。不确定触发器如何帮助我确保数据完整性?如果Employee.is_deleted=false,则Company.is_deleted=false也应为true。触发器可以保证吗?触发器提供的保证与声明性约束提供的保证不同,但可以这样编写触发器:如果将companys.is_deleted更改为true,将执行一条SQL语句,将该公司的employees.is_deleted设置为true。