微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何为2列指定唯一约束,在PostgreSQL中应将其视为一列?

假设我有一张桌子:

    table people (
    user,path1,path2,);

我想限制它,如果列path1或path2中已经存在一个具有相同名称的记录,它将限制添加/更新。

示例:

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

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

在第二次插入时,应该出现错误,因为在第一次录制的路径2中已经定义了“多伦多” 。

解决方法

从理论上讲,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 && );

以上导致错误:

错误:数据类型为text []的访问方法“ gist”没有默认的操作符类


但是&&运算符适用于整数数组。因此,如果“路径”列可以转换为整数,例如引用查找表的外键,可以通过以下方式实现:

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 =,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",path2)
values ('George',2,3);

错误将是:

错误:键值冲突违反排除约束“ check_path”
详细信息:密钥(“ user”,(ARRAY [path1,path2]))=(George,{2,3})与现有密钥(“ user”,(ARRAY [path1,path2]))=(George,{ 1,2})。

Online example

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。