Postgresql postgres中相对于其他行的部分唯一索引
一般来说,我知道PostgreSQL中有部分唯一索引,但我需要加入一个约束,我认为它不适合部分索引领域。或者也许有一种表达方式 最小示例Postgresql postgres中相对于其他行的部分唯一索引,postgresql,unique-constraint,Postgresql,Unique Constraint,一般来说,我知道PostgreSQL中有部分唯一索引,但我需要加入一个约束,我认为它不适合部分索引领域。或者也许有一种表达方式 最小示例 CREATE TABLE table (user INT, type INT, flag BOOL, text VARCHAR (50)); 这些要求是: 用户可以有多行相同的类型,但前提是标志为false 如果用户有一行具有特定类型和标志设置为true,则该用户和类型不能有其他行 例如,如果表中有以下行: | user | type | flag | t
CREATE TABLE table (user INT, type INT, flag BOOL, text VARCHAR (50));
这些要求是:
用户
可以有多行相同的类型
,但前提是标志
为false用户
有一行具有特定类型
和标志
设置为true,则该用户
和类型
不能有其他行| user | type | flag | text |
| 1 | 1 | false | foo |
| 1 | 1 | false | bar |
然后我们不能插入(1,1,true,'whatever')
此外,如果表中包含:
| user | type | flag | text |
| 1 | 1 | true | foo |
我们不能插入(1,1,false,'bar')或(1,1,true,'baz'))
在PostgreSQL中有没有一种方法可以表达这样的约束?您需要a和a的组合。不幸的是,在排除约束中没有可用于布尔列的运算符族,因此可以使用整数列。需要为整型列模拟gist索引
create extension if not exists btree_gist;
表定义(标识符稍微修改):
drop table if exists my_table;
create table my_table (
user_id integer,
type_id integer,
flag integer check (flag in (0, 1)),
text varchar (50),
exclude using gist (user_id with =, type_id with =, flag with <>)
);
create unique index on my_table (user_id, type_id) where flag = 1;
insert into my_table
values
(1, 1, 0, 'foo'),
(1, 1, 0, 'bar'),
(2, 2, 1, 'foo');
INSERT 0 3
insert into my_table
values
(1, 1, 1, 'whatever');
ERROR: conflicting key value violates exclusion constraint "my_table_user_id_type_id_flag_excl"
DETAIL: Key (user_id, type_id, flag)=(1, 1, 1) conflicts with existing key (user_id, type_id, flag)=(1, 1, 0).
insert into my_table
values
(2, 2, 0, 'whatever');
ERROR: conflicting key value violates exclusion constraint "my_table_user_id_type_id_flag_excl"
DETAIL: Key (user_id, type_id, flag)=(2, 2, 0) conflicts with existing key (user_id, type_id, flag)=(2, 2, 1).
insert into my_table
values
(2, 2, 1, 'whatever');
ERROR: duplicate key value violates unique constraint "my_table_user_id_type_id_idx"
DETAIL: Key (user_id, type_id)=(2, 2) already exists.