两列上的唯一索引,反之亦然
Unique Index on two columns and vice versa
我在 postgres 9.5 中有以下 table:
CREATE TABLE public.test
(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer,
id2 integer,
CONSTRAINT test_pkey PRIMARY KEY (id)
);
我想在两列上添加限制,只允许
处的记录集
- 新记录集 (id1,id2) 不存在并且
- 新记录集 (id1,id2) 不存在 (id2,id1) 并且
- 新记录集的id1和id2不相等
它应该是这样的:
id | id1 | id2
---------------
1 | 1 | 1 <-- invalid (violates restriction 3.)
2 | 1 | 2 <-- valid
3 | 1 | 2 <-- invalid (violates restriction 1.)
4 | 2 | 1 <-- invalid (violates restriction 2.)
5 | 3 | 1 <-- valid
6 | 3 | 2 <-- valid
对于限制1,我添加了:
ALTER TABLE test ADD CONSTRAINT test_id1_id2_unique UNIQUE(id1, id2);
但是如何为 2. 和 3. 添加约束?
在a_horse_with_no_name帮助下的最终解决方案:
CREATE TABLE public.test(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer NOT NULL,
id2 integer NOT NULL,
CONSTRAINT test_pkey PRIMARY KEY (id),
CONSTRAINT test_check CHECK (id1 <> id2)
);
CREATE UNIQUE INDEX test_id1_id2_unique
ON public.test
USING btree
((LEAST(id1, id2)), (GREATEST(id1, id2)));
您可以创建一个唯一索引来涵盖 1. 和 2.
create unique index on test ( least(id1,id2), greatest(id1,id2) );
对于 3. 你需要一个检查约束:
CREATE TABLE public.test
(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer,
id2 integer,
constraint check_not_equal check (id1 is distinct from id2),
CONSTRAINT test_pkey PRIMARY KEY (id)
);
您可能希望两个 ID 都为 NOT NULL
。在这种情况下,您还可以使用 check (id1 <> id2)
我在 postgres 9.5 中有以下 table:
CREATE TABLE public.test
(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer,
id2 integer,
CONSTRAINT test_pkey PRIMARY KEY (id)
);
我想在两列上添加限制,只允许
处的记录集- 新记录集 (id1,id2) 不存在并且
- 新记录集 (id1,id2) 不存在 (id2,id1) 并且
- 新记录集的id1和id2不相等
它应该是这样的:
id | id1 | id2
---------------
1 | 1 | 1 <-- invalid (violates restriction 3.)
2 | 1 | 2 <-- valid
3 | 1 | 2 <-- invalid (violates restriction 1.)
4 | 2 | 1 <-- invalid (violates restriction 2.)
5 | 3 | 1 <-- valid
6 | 3 | 2 <-- valid
对于限制1,我添加了:
ALTER TABLE test ADD CONSTRAINT test_id1_id2_unique UNIQUE(id1, id2);
但是如何为 2. 和 3. 添加约束?
在a_horse_with_no_name帮助下的最终解决方案:
CREATE TABLE public.test(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer NOT NULL,
id2 integer NOT NULL,
CONSTRAINT test_pkey PRIMARY KEY (id),
CONSTRAINT test_check CHECK (id1 <> id2)
);
CREATE UNIQUE INDEX test_id1_id2_unique
ON public.test
USING btree
((LEAST(id1, id2)), (GREATEST(id1, id2)));
您可以创建一个唯一索引来涵盖 1. 和 2.
create unique index on test ( least(id1,id2), greatest(id1,id2) );
对于 3. 你需要一个检查约束:
CREATE TABLE public.test
(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
id1 integer,
id2 integer,
constraint check_not_equal check (id1 is distinct from id2),
CONSTRAINT test_pkey PRIMARY KEY (id)
);
您可能希望两个 ID 都为 NOT NULL
。在这种情况下,您还可以使用 check (id1 <> id2)