PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Crie um índice de várias colunas para impor exclusividade


Isso parece ser um mal-entendido.

Sua citação da minha resposta é um pouco enganosa, pois só se aplica se você também criar o índice parcial adicional conforme descrito lá:
Como adicionar um índice exclusivo condicional no PostgreSQL

Se você não adicionar este segundo índice (como não adicionou), você já tem sua solução , parece. Apenas com o índice exclusivo de várias colunas, você pode inserir (1, NULL) várias vezes, mas (1,2) ou (1,3) apenas uma vez.

Strings vazias


Se, por engano, você estava considerando strings vazias ('' ) (para um tipo de caractere ) em vez de NULL valores:esses são tratados como qualquer outro valor. Você poderia lidar com essa situação usando um índice exclusivo de várias colunas e parcialmente funcional (índice em uma expressão ):
CREATE UNIQUE INDEX predictions _dim_tat_uni_idx
ON predictions (tat, NULLIF(dim, ''));

Desta forma, você pode inserir (1, 'a') , (1, 'b') apenas uma vez.
Mas (1, NULL) e (1, '') várias vezes.

Efeitos colaterais


O índice ainda suportaria totalmente consultas simples na primeira coluna (tat ).
Mas as consultas em ambas as colunas teriam que corresponder à expressão para utilizar todo o potencial. Isso seria mais rápido, mesmo que não pareça fazer sentido:
SELECT * FROM predictions
WHERE  tat = 1
AND    NULLIF(dim, '') = 'foo';

.. do que isso:
SELECT * FROM predictions
WHERE  tat = 1
AND    dim = 'foo';

.. porque a primeira consulta pode usar ambas as colunas de índice. O resultado seria o mesmo (exceto ao pesquisar por '' ou NULL ). Detalhes nesta resposta relacionada em dba.SE .