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

Postgresql 涉及另一个表的列的可空列的约束,postgresql,database-design,foreign-keys,constraints,unique-constraint,Postgresql,Database Design,Foreign Keys,Constraints,Unique Constraint,我有两张桌子: table1: id bigserial not null, value1 integer not null table2: id bigserial not null, table1_id bigint not null,(FK) value2 character varying not null, value3 character varying, 我需要添加一些约束,以确保当value3不为空时,value3、value2和table1的组合。每个table2,valu

我有两张桌子:

table1:
id bigserial not null,
value1 integer not null

table2:
id bigserial not null,
table1_id bigint not null,(FK)
value2 character varying not null,
value3 character varying,

我需要添加一些约束,以确保当
value3
不为空时,
value3
value2
table1的组合。每个
table2
,value1
应该是唯一的。我怎么做

对于初学者,可以使用部分唯一索引

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

这并不说明
表1
中的
value1
值重复。由于所有相关约束只涉及同一表的列,因此,如果没有肮脏的技巧,就无法使用约束强制执行此操作

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

执行此操作的一种方法是将
value1
以冗余方式存储在
table2
中,在更新层叠时使用
添加多列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;
相关的:

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


你的Postgres版本?和
表1.value1
的定义是否唯一?(
table1.id
显然需要PK或唯一约束才能允许FK。)写入模式?
表1是否为只读?表1.value1不是唯一的。表1.id是一个PK。Postgres 9.4版请提问以提供完整信息。注释不在此处。表1中的Value1可以重复