可空列的约束涉及另一个表的列

时间:2018-01-08 16:32:14

标签: postgresql database-design foreign-keys constraints unique-constraint

我有两张桌子:

value3

我需要添加一些约束以确保当value3不为空时,value2table1.value1table2的组合应该是唯一的{{ 1}}。我该怎么做?

1 个答案:

答案 0 :(得分:1)

对于初学者,你可以有一个部分独特的索引

CREATE UNIQUE INDEX table2_foo_idx ON table2 (value3, value2, table1_id)`
WHERE value3 IS NOT NULL;

相关:

这并未考虑value1table1的重复值。这不能通过没有脏技巧的约束来强制执行,因为所有相关约束只涉及同一个表的列。

根据完整情况,有各种变通办法。触发器,使用伪不可变函数的部分函数唯一多列索引,(NOT VALIDCHECK约束...

一种 clean 强制执行此操作的方法是将value1冗余地存储在table2中,使用ON UPDATE CASCADE添加多列FK约束,创建上面提到的唯一索引:

CREATE TABLE table1 (
   table1_id bigserial PRIMARY KEY
 , value1    text NOT NULL
 , UNIQUE   (value1, table1_id)  -- logically redundant, neede for FK
);

CREATE TABLE table2 (
   table2_id bigserial PRIMARY KEY
 , table1_id bigint NOT NULL
 , value1    text NOT NULL
 , value2    text NOT NULL
 , value3    text
 , FOREIGN KEY (table1_id, value1) REFERENCES table1(table1_id, value1) ON UPDATE CASCADE
);

CREATE UNIQUE INDEX table2_foo_idx ON table2 (value3, value2, value1)`
WHERE value3 IS NOT NULL;

相关:

在您的唯一索引和约束中选择适当的列顺序,以便在不添加更多索引的情况下最佳地支持典型查询。比较: