复合 FK 上的部分“ON DELETE SET NULL”

问题描述 投票:0回答:4

我在 PostgreSQL 数据库中有一组表,将它们称为

employee
corporation
account
corporation
有一个指向
account
的外键(“帐户”是一个“企业帐户”,跨越一个或多个公司,而不是用于登录系统的“用户帐户”),并且
employee
具有
corporation
的复合外键和
account
的外键(它有两列:
corporation_id
account_id
corporation
的外键使用两列)。

如果删除

employee
的父
corporation
行,我希望将其
corporation_id
列的值设置为
NULL
,但
account_id
列应保留其值。

这个想法是,员工必须“属于”一个帐户(因此

employee.account_id
NOT NULL
),并且可以分配给该帐户内的任何(或没有)公司。 如果公司被删除,则分配给该公司的任何员工都应取消分配(
employee.corporation_id
设置为
NULL
),但他们仍应“属于”该帐户(
employee.account_id
应保留其值)。

外键上的

ON DELETE SET NULL
会设置
corporation (id, account_id)
corporation_id
account_id
    

postgresql foreign-keys
4个回答
2
投票

首先,为corporation_id
    NULL
  1. 创建外键约束。
    其次,为复合键 
  2. FOREIGN KEY (corporation_id) REFERENCES corporation(id) ON DELETE SET NULL
  3. 创建另一个外键约束,仅这次不使用
    FOREIGN KEY (corporation_id, account_id) REFERENCES corporation(id, account_id)
    
    
  4. 请注意,创建约束的顺序很重要!由于第二个约束默认为
ON DELETE

,因此仅当检查约束时仍然存在任何引用行时才会引发错误。但是,因为我们的第一个约束将corporation_id设置为

NO ACTION
,所以引用行不再存在,并且一切正常。
    


1
投票

如果你只需要能完成这项工作的东西,我可以想到两种解决方法:

具有用于员工和公司之间连接的附加表:
  • 创建一个包含字段
      employee_id、corporation_id、account_id
    1. 的表。 外键
    2. (employee_id, account_id)
    3. ref employee(corporation_id, account_id) ref corporation with DELETE CASCADE 如果要求员工只能在一家公司工作 - 添加对(employee_id,account_id)的唯一约束
    4. 最后,员工表中的corporate_id将不会被使用
    或者从加入中删除 account_id 并使用触发器来验证公司 account_id 是否与员工 account_id 相同

0
投票
NULL

(

employee
) 中添加了一个额外的列,用于
current_account_id
的外键,带有
corporation
,以及
DELETE SET NULL
的检查约束。 只有级联
current_account_id = account_id
发生了变化:如果
id
发生了变化,它会级联到
account.id
(通过
employee.account_id
的外键到
employee
)和
account
(通过
employee.current_account_id
的外键到
employee
corporation
,通过
corporation
的外键到
account
),并且在某些时候它们是不同的(它们显然不是原子更新的),并且它违反了检查约束,PostgreSQL不允许延迟。 因此,我将其更改为约束触发器,如果值不同,它会引发
check_constraint
,并且 is 可延迟(并且最初是延迟的)。


0
投票

从 Postgresql v15.0 开始,您可以通过随后指定列列表来指定哪些列设置为 null(即

ON DELETE SET NULL
因此,对于您的示例,以下内容与您想要的类似:

ON DELETE SET NULL (column_name)

	
© www.soinside.com 2019 - 2024. All rights reserved.