条件PostgreSQL外键

tre*_*005 10 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),所有这些都意味着不同的东西.

笔记:

我完全清楚这是一个糟糕的桌面设计,但它是10多年前建立的一个聪明的技巧,当时我们现有的功能和资源都不存在.这个系统正在运行数百个零售店,所以要回去并且此时改变方法可能需要几个月我们没有.

我不能使用触发器,这必须用外键完成.

Mik*_*sen 5

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

  1. 只是没有 FK 约束。将此逻辑移至数据访问层,无需参照完整性即可生存。
  2. 允许NULL在列中,即使使用 FK 约束也是完全有效的。然后,使用另一列来存储0和的含义-1
  3. 在引用表中为0和添加一个虚拟行-1。即使它只有虚假数据,它也会满足 FK 约束。

希望这可以帮助!

  • 选项 4 总是修改 Postgres 代码,它*是*你知道的开源:) (3认同)

A.H*_*.H. 4

您可以添加另一个“影子”列来table1保存已清理的值(即除0和之外的所有值-1)。使用此列进行引用完整性检查。该影子列由一个简单的触发器更新/填充,该触发器将除和table1之外的所有值写入影子列。和都可以映射到.0-10-1null

然后您就拥有参考完整性和未更改的原始列。缺点:您还有一个小触发器和一些冗余数据。但可惜,这就是遗留模式的命运!

  • @AH 但是 PostgreSQL,像所有开源项目一样,不是由 TODO 列表驱动的,而是由那些积极困扰那些愿意接受它们的人的事情驱动的。虽然我怀疑 PostgreSQL 团队是否愿意针对这个特定问题集成修复程序,但我也确信他们会愿意考虑一个为 PostgreSQL 提供条件外键的工作补丁,如果可以设计某种合理的 SQL 语法来支持构造。当然,建议与团队合作来定义这种语法。它是开源的、可工作的代码对话。 (2认同)