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
.