No Postgresql, force exclusivo na combinação de duas colunas


192

Gostaria de configurar uma tabela no PostgreSQL para que duas colunas juntas sejam únicas. Pode haver vários valores de um ou outro valor, desde que não haja dois que compartilhem os dois.

Por exemplo:

CREATE TABLE someTable (
    id int PRIMARY KEY AUTOINCREMENT,
    col1 int NOT NULL,
    col2 int NOT NULL
)

Então, col1e col2pode repetir, mas não ao mesmo tempo. Portanto, isso seria permitido (sem incluir o ID)

1 1
1 2
2 1
2 2

mas não isso:

1 1
1 2
1 1 -- would reject this insert for violating constraints

Como este é um resultado de pesquisa de classificação superior no google, talvez seja melhor fornecer também a tabela alter exist
ϻαϻɾΣɀО-MaMrEzO

Respostas:


228
CREATE TABLE someTable (
    id serial primary key,
    col1 int NOT NULL,
    col2 int NOT NULL,
    unique (col1, col2)
)

autoincrementnão é postgresql. Você quer um serial.

Se col1 e col2 criarem um único e não puderem ser nulos, eles criarão uma boa chave primária:

CREATE TABLE someTable (
    col1 int NOT NULL,
    col2 int NOT NULL,
    primary key (col1, col2)
)

6
Eu gosto da sugestão de uma chave primária sobre única aqui, porque não permitimos valores NULL neste caso. De docs PostgeSQL: "Note-se que uma restrição exclusiva não, por si só, fornecer um identificador único, porque não exclui os valores nulos)." Postgresql.org/docs/8.1/static/ddl-constraints.html#AEN2038
ndequeker

Como posso implementar isso na definição de esquema?
wagng

2
Em alguns cenários, convém que uma chave substituta seja usada como chave primária, em vez de uma combinação de colunas. Em particular, para melhorar o desempenho ao fazer junções em grandes volumes de dados. Pessoalmente, optei pela solução UNIQUE CONSTRAINT abaixo.
Alexis.Rolland

1
É possível impor uma restrição única em apenas uma permutação, como única (col1, col2 = '1')?
Vikram Khemlani 12/11/19


160

Crie uma restrição exclusiva de que dois números juntos NÃO PODEM ser repetidos juntos:

ALTER TABLE someTable
ADD UNIQUE (col1, col2)

18

Parece regular restrição UNIQUE :)

CREATE TABLE example (
a integer,
b integer,
c integer,
UNIQUE (a, c));

Mais aqui


1
Isso adiciona um índice para ae um índice para cindependentemente? Porque eu preciso encontrar rapidamente com base em aalgumas vezes, e rapidamente encontrar com base em calgumas vezes.
CMCDragonkai
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.