跨两列的 Postgres 唯一约束?
Postgres unique constraint across two columns?
这是我当前的数据库结构:
Col1 Col2
1 abc123
1 abc123
1 def321
2 xyz789
2 xyz789
我想确保 Col2
中的任何条目仅用于 Col1
中的相同条目。例如,数据库会让您添加此行:
Col1 Col2
2 lmn456
但不是这个:
Col1 Col2
2 abc123
有没有办法用唯一索引强制执行此操作?通常,unique 强制特定组合对于整个 table 是唯一的(即 (1,abc123)
只出现一次)。
我无法将 Col2
移动到另一个 table 并使用连接,因为我需要为 Col1
中的每个条目支持 Col2
的多个值 -这不是一对一。
没有。你有错误的数据结构。
您应该将 col2
存储在单独的 table 一行中,每个 col1
和 col2
。然后您可以使用 join
.
查找值
这是使用 exclude constraint.
的典型案例
约束将使用 btree 运算符 <>
和 =
,因此您必须安装 btree_gist extension.
create extension if not exists btree_gist;
create table my_table(
col1 int,
col2 text,
exclude using gist (col1 with <>, col2 with =)
);
测试:
insert into my_table values
(1, 'abc123'),
(1, 'abc123'),
(1, 'def321'),
(2, 'xyz789'),
(2, 'xyz789')
returning *;
col1 | col2
------+--------
1 | abc123
1 | abc123
1 | def321
2 | xyz789
2 | xyz789
(5 rows)
insert into my_table
values (2, 'abc123');
ERROR: conflicting key value violates exclusion constraint "my_table_col1_col2_excl"
DETAIL: Key (col1, col2)=(2, abc123) conflicts with existing key (col1, col2)=(1, abc123).
这是我当前的数据库结构:
Col1 Col2
1 abc123
1 abc123
1 def321
2 xyz789
2 xyz789
我想确保 Col2
中的任何条目仅用于 Col1
中的相同条目。例如,数据库会让您添加此行:
Col1 Col2
2 lmn456
但不是这个:
Col1 Col2
2 abc123
有没有办法用唯一索引强制执行此操作?通常,unique 强制特定组合对于整个 table 是唯一的(即 (1,abc123)
只出现一次)。
我无法将 Col2
移动到另一个 table 并使用连接,因为我需要为 Col1
中的每个条目支持 Col2
的多个值 -这不是一对一。
没有。你有错误的数据结构。
您应该将 col2
存储在单独的 table 一行中,每个 col1
和 col2
。然后您可以使用 join
.
这是使用 exclude constraint.
的典型案例约束将使用 btree 运算符 <>
和 =
,因此您必须安装 btree_gist extension.
create extension if not exists btree_gist;
create table my_table(
col1 int,
col2 text,
exclude using gist (col1 with <>, col2 with =)
);
测试:
insert into my_table values
(1, 'abc123'),
(1, 'abc123'),
(1, 'def321'),
(2, 'xyz789'),
(2, 'xyz789')
returning *;
col1 | col2
------+--------
1 | abc123
1 | abc123
1 | def321
2 | xyz789
2 | xyz789
(5 rows)
insert into my_table
values (2, 'abc123');
ERROR: conflicting key value violates exclusion constraint "my_table_col1_col2_excl"
DETAIL: Key (col1, col2)=(2, abc123) conflicts with existing key (col1, col2)=(1, abc123).