我在Postgres中有一个多对多联接表,我想索引到A)提高性能(显然)和B)强制唯一性。例如:
a_id | b_id 1 | 2 <- okay 1 | 3 <- okay 2 | 3 <- okay 1 | 3 <- not okay (same as row 2)
是否可以在两列上使用一个索引来强制值唯一?我应该使用哪种类型的索引?
如果该唯一键是主键,请执行以下操作:
create table tbl( a_id int not null, b_id int not null, constraint tbl_pkey primary key(a_id,b_id) );
如果唯一是非主键,请执行以下操作:
create table tbl( -- other primary key here, e.g.: -- id serial primary key, a_id int not null, b_id int not null, constraint tbl_unique unique(a_id,b_id) );
如果您已有表,请执行以下操作:
alter table tbl add constraint tbl_unique unique(a_id, b_id)
该更改表显示以下消息:
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "tbl_unique" for table "tbl" Query returned successfully with no result in 22 ms.
如果您想删除该约束(您可能希望通过3个字段的组合来使其唯一):
ALTER TABLE tbl DROP CONSTRAINT tbl_unique;
关于索引,来自Postgres doc:
当为表定义唯一约束或主键时,PostgreSQL自动创建唯一索引
资料来源:http : //www.postgresql.org/docs/9.1/static/indexes- unique.html
如果唯一性取决于某些规则,则应使用CREATE UNIQUE INDEX,例如:
CREATE UNIQUE INDEX
鉴于这种:
CREATE TABLE tbl ( a_id integer NOT NULL, b_id integer NULL ); alter table tbl add constraint tbl_unique unique(a_id, b_id);
唯一可以捕获这些重复项,这将被数据库拒绝:
insert into tbl values (1,1), (1,1);
但是,UNIQUE CONSTRAINT无法捕获重复的null。空值用作未知数,它们用作通配符,这就是为什么允许在唯一约束中具有多个空值的原因。这将被数据库接受:
insert into tbl values (1,1), (1,null), -- think of this null as wildcard, some real value can be assigned later. (1,null); -- and so is this. that's why both of these nulls are allowed
考虑一下UNIQUE CONSTRAINT它允许延迟唯一性,因此可以接受上面的空值。
UNIQUE CONSTRAINT
如果除了唯一约束之外,每个a_id只需要一个通配符(null b_id),则需要添加一个UNIQUE INDEX。UNIQUE CONSTRAINT上不能有表达式。 INDEX并且UNIQUE INDEX可以。这将是您用于拒绝多个null的完整DDL;
UNIQUE INDEX
INDEX
这将是您完整的DDL:
CREATE TABLE tbl ( a_id integer NOT NULL, b_id integer NULL ); alter table tbl add constraint tbl_unique unique(a_id, b_id); create unique index tbl_unique_a_id on tbl(a_id) where b_id is null;
现在,您的数据库将拒绝此操作:
insert into tbl values (1,1), (1,null), (1,null);
这将被允许:
insert into tbl values (1,1), (1,null);
与http://www.ienablemuch.com/2010/12/postgresql-said-sql-server2008-said- non.html相关