如何为在 PostgreSQL 中应视为一列的 2 列指定唯一约束?

How do I specify unique constraint for 2 columns that should be treated as one in PostgreSQL?

假设我有一个 table:

    table people (
    user,
    path1,
    path2,
);

如果列 path1 或 path2 中已有同名记录,我想限制 adding/updating。

示例:

INSERT INTO people (user, path1, path2)
VALUES ('George', 'New York', 'Toronto',);

INSERT INTO people (user, path1, path2)
VALUES ('Joe', 'Toronto', 'LA',);

在第二次插入时,应该会出现错误,因为'Toronto'已经在第一个记录的path2中定义了。

理论上 exclusion constraint 可以解决这个问题。

但是,下面的代码不起作用

create table people 
(
  "user" text,
  path1 text,
  path2 text
);

alter table people 
  add constraint check_path
  exclude using gist ("user" with =, (array[path1, path2]) with && );

以上导致错误:

ERROR: data type text[] has no default operator class for access method "gist"


But&& 运算符适用于整数数组。因此,如果“路径”列可以变成一个整数,例如引用查找的外键 table,这可以通过以下方式实现:

create table location
(
  id integer primary key, 
  name varchar(50) not null unique
);

create table people 
(
  "user" text,
  path1 int not null references location,
  path2 int not null references location
);

alter table people 
  add constraint check_path
  exclude using gist ("user" with =, (array[path1, path2]) with && );
  
insert into location (id, name)
values 
(1, 'New York'),
(2, 'Toronto'),
(3, 'LA');

那么这个插入显然会起作用:

insert into people ("user", path1, path2)
values 
  ('George', 1, 2);

但这会导致错误:

insert into people ("user", path1, path2)
values ('George', 2, 3);

错误将是:

ERROR: conflicting key value violates exclusion constraint "check_path"
DETAIL: Key ("user", (ARRAY[path1, path2]))=(George, {2,3}) conflicts with existing key ("user", (ARRAY[path1, path2]))=(George, {1,2}).

Online example