Estou usando o SQL Server 2005. Quero restringir os valores em uma coluna para serem exclusivos, permitindo NULLS.
Minha solução atual envolve um índice exclusivo em uma exibição como esta:
CREATE VIEW vw_unq WITH SCHEMABINDING AS
SELECT Column1
FROM MyTable
WHERE Column1 IS NOT NULL
CREATE UNIQUE CLUSTERED INDEX unq_idx ON vw_unq (Column1)
Alguma ideia melhor?
sql
sql-server
indexing
constraints
unique
Nuno G
fonte
fonte
Respostas:
Tenho certeza de que você não pode fazer isso, pois viola o propósito dos únicos.
No entanto, essa pessoa parece ter uma solução decente: http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html
fonte
Usando o SQL Server 2008, você pode criar um índice filtrado: http://msdn.microsoft.com/en-us/library/cc280372.aspx . (Vejo que Simon adicionou isso como um comentário, mas pensei que merecia sua própria resposta, pois o comentário é facilmente esquecido.)
Outra opção é um gatilho para verificar a exclusividade, mas isso pode afetar o desempenho.
fonte
create unique index UIX on MyTable (Column1) where Column1 is not null
ANSI_NULLS
estáON
, caso contrário, você obterá um erro ao tentar inserir dados.O truque da coluna calculada é amplamente conhecido como "nullbuster"; minhas notas creditam a Steve Kass:
fonte
Estritamente falando, uma coluna anulável exclusiva (ou conjunto de colunas) pode ser NULL (ou um registro de NULLs) apenas uma vez, visto que ter o mesmo valor (e isso inclui NULL) mais de uma obviamente viola a restrição exclusiva.
No entanto, isso não significa que o conceito de "colunas anuláveis exclusivas" seja válido; para realmente implementá-lo em qualquer banco de dados relacional, só temos que ter em mente que este tipo de banco de dados deve ser normalizado para funcionar corretamente, e a normalização geralmente envolve a adição de várias tabelas extras (não-entidades) para estabelecer relacionamentos entre as entidades .
Vamos trabalhar um exemplo básico considerando apenas uma "coluna anulável única", é fácil expandi-la para mais colunas.
Suponha que as informações representadas por uma tabela como esta:
Podemos fazer isso separando uniqnull e adicionando uma segunda tabela para estabelecer uma relação entre valores uniqnull e the_entity (em vez de ter uniqnull "dentro" da_entidade):
Para associar um valor de uniqnull a uma linha na entidade, precisamos também adicionar uma linha na relação.
Para linhas em the_entity onde nenhum valor uniqnull está associado (ou seja, para aqueles que colocaríamos NULL em the_entity_incorrect), simplesmente não adicionamos uma linha em the_relation.
Observe que os valores para uniqnull serão únicos para toda a relação, e também observe que para cada valor na entidade pode haver no máximo um valor na relação, uma vez que as chaves primária e externa obrigam isso.
Então, se um valor de 5 para uniqnull deve ser associado a um id the_entity de 3, precisamos:
E, se um valor de id de 10 para the_entity não tiver uma contraparte única, fazemos apenas:
Para desnormalizar essas informações e obter os dados que uma tabela como the_entity_incorrect manteria, precisamos:
O operador "left outer join" garante que todas as linhas de the_entity apareçam no resultado, colocando NULL na coluna uniqnull quando nenhuma coluna correspondente estiver presente na relação.
Lembre-se de que qualquer esforço despendido por alguns dias (ou semanas ou meses) no projeto de um banco de dados bem normalizado (e as visualizações e procedimentos desnormalizantes correspondentes) poupará anos (ou décadas) de dor e desperdício de recursos.
fonte