条件PostgreSQL外键

时间:2012-06-05 16:00:54

标签: postgresql

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多年前建立的一个聪明的技巧,当时我们现有的功能和资源都不存在。这个系统正在运行数百个零售店,所以要回去并且此时改变方法可能需要几个月我们没有。

     

我不能使用触发器,必须使用外键

5 个答案:

答案 0 :(得分:2)

简短的回答是否定的,Postgres没有条件外键。您可能会考虑的一些选项是:

  1. 只是没有FK约束。将此逻辑移至数据访问层并在没有参照完整性的情况下生存。
  2. 在列中允许NULL,即使使用FK约束也完全有效。然后,使用另一列来存储0-1的含义。
  3. 0-1的引用表中添加虚拟行。即使它只是伪造数据,也会满足FK约束。
  4. 希望这有帮助!

答案 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关系。