Como chave primária
Faça isso se esse exclusivo for a chave primária:
create table tbl(
a_id int not null,
b_id int not null,
constraint tbl_pkey primary key(a_id,b_id)
);
Não é chave primária
Faça isso se esse exclusivo for uma chave não primária:
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)
);
Tabela existente
Se você tiver uma tabela existente, faça isso:
alter table tbl
add constraint tbl_unique unique(a_id, b_id)
Essa tabela alter exibe esta mensagem:
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "tbl_unique" for table "tbl"
Query returned successfully with no result in 22 ms.
Descartar
Se você quiser eliminar essa restrição (você pode querer tornar única uma combinação de 3 campos):
ALTER TABLE tbl DROP CONSTRAINT tbl_unique;
Índice e restrição e nulos
Em relação ao índice, do documento do Postgres:
Fonte:http://www.postgresql.org/docs/9.1 /static/indexes-unique.html
Se a exclusividade depende de algumas regras, você deve usar
CREATE UNIQUE INDEX
, por exemplo:Dado isso:
CREATE TABLE tbl
(
a_id integer NOT NULL,
b_id integer NULL
);
alter table tbl
add constraint tbl_unique unique(a_id, b_id);
Esse único pode pegar essas duplicatas, isso será rejeitado pelo banco de dados:
insert into tbl values
(1,1),
(1,1);
No entanto, essa UNIQUE CONSTRAINT não pode capturar nulos duplicados. Nulls serve como desconhecido, serve como curinga, é por isso que é permitido ter vários nulos em restrição exclusiva. Isso será aceito pelo banco de dados:
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
Pense em
UNIQUE CONSTRAINT
que permite exclusividade diferida, daí a aceitação de valores nulos acima. Se você quiser apenas um curinga (null b_id) por a_id, além da restrição exclusiva, você precisa adicionar um
UNIQUE INDEX
. UNIQUE CONSTRAINT não pode ter uma expressão neles. INDEX
e UNIQUE INDEX
posso. Este será seu DDL completo para rejeitar múltiplos nulos; Este será o seu DDL completo:
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;
Isso será rejeitado pelo seu banco de dados agora:
insert into tbl values
(1,1),
(1,null),
(1,null);
Isso será permitido:
insert into tbl values
(1,1),
(1,null);
Relacionado a http://www.ienablemuch .com/2010/12/postgresql-said-sql-server2008-said-non.html