我有两张桌子:
value3
我需要添加一些约束以确保当value3
不为空时,value2
,table1.value1
和table2
的组合应该是唯一的{{ 1}}。我该怎么做?
答案 0 :(得分:1)
对于初学者,你可以有一个部分独特的索引
CREATE UNIQUE INDEX table2_foo_idx ON table2 (value3, value2, table1_id)`
WHERE value3 IS NOT NULL;
相关:
但这并未考虑value1
中table1
的重复值。这不能通过没有脏技巧的约束来强制执行,因为所有相关约束只涉及同一个表的列。
根据完整情况,有各种变通办法。触发器,使用伪不可变函数的部分函数唯一多列索引,(NOT VALID
)CHECK
约束...
一种 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;
相关:
在您的唯一索引和约束中选择适当的列顺序,以便在不添加更多索引的情况下最佳地支持典型查询。比较: