PostgreSQL中是否可以有条件地添加外键?
类似于:ALTER TABLE table1 ADD FOREIGN KEY (some_id) REFERENCES other_table WHERE some_id NOT IN (0,-1) AND some_id IS NOT NULL;
具体来说,我的引用表具有所有正整数(1+),但我需要添加外键的表可以包含零(0),空和负一(-1),所有这些都意味着不同的东西。 / p>
注意:
我完全清楚这是一个糟糕的桌面设计,但它是10多年前建立的一个聪明的技巧,当时我们现有的功能和资源都不存在。这个系统正在运行数百个零售店,所以要回去并且此时改变方法可能需要几个月我们没有。
我不能使用触发器,必须使用外键。
答案 0 :(得分:2)
简短的回答是否定的,Postgres没有条件外键。您可能会考虑的一些选项是:
NULL
,即使使用FK约束也完全有效。然后,使用另一列来存储0
和-1
的含义。0
和-1
的引用表中添加虚拟行。即使它只是伪造数据,也会满足FK约束。希望这有帮助!
答案 1 :(得分:2)
您的要求等同于此检查约束:
create table t (a float check (a >= -1 and a = floor(a) or a is null));
答案 2 :(得分:1)
您可以向table1
添加另一个“阴影”列,其中包含已清理的值(即除0
和-1
之外的所有内容)。使用此列进行参照完整性检查。此影子列由table1
上的简单触发器更新/填充,该触发器将除0
和-1
之外的所有值都写入影子列。 0
和-1
都可以映射到null
。
然后您具有参考完整性和未更改的原始列。缺点:你还有一点触发器和一些冗余数据。但唉,这是传统架构的命运!
答案 3 :(得分:1)
您可以使用检查约束和外键来实现此功能。
CREATE TABLE table1 (some_id INT, some_id_fkey INT REFERENCES other_table(other_id), CHECK (some_id IN (0,-1) OR some_id IS NOT DISTINCT FROM some_id_fkey));
(未经测试)
答案 4 :(得分:0)
这是另一种可能性。使用PG继承强制表的分区在标志列中具有+1,否则。 (通常的规则/触发器用于维护它。)然后在Has_PLUS_ONE子表和引用表之间建立FK关系。