De acordo com a CREATE INDEX
documentação:
Até 16 colunas podem ser combinadas em uma única chave de índice composta.
Temos uma tabela com ~ 18 colunas que precisam formar uma combinação única. Esta tabela não é sensível ao desempenho - raramente atualizamos valores / inserimos registros. Só precisamos garantir que evitamos duplicar nossos registros ... e pensamos que poderíamos impor uma restrição de exclusividade simples.
Alguma ideia? Estou aberto a evitar inteiramente o índice / restrição exclusivo, se houver uma maneira melhor.
Respostas:
Adicione uma coluna computada persistente que combine as 18 teclas e crie um índice exclusivo na coluna computada:
Consulte Criando índices em colunas computadas .
Outra abordagem é criar uma exibição indexada:
Consulte Criando vistas indexadas .
Ambas as abordagens permitem um agregado de chave parcial: agregado c1 + c2 + c3 como k1, c4 + c5 + c6 como k2 etc., em seguida, indexa / cria uma exibição indexada em (k1, k2, ...). Tia pode ser benéfico para varreduras de intervalo (o índice pode ser usado para pesquisa em c1 + c2 + c3.
Obviamente, todas as
+
operações no meu exemplo são agregação de cadeias, o operador real a ser usado depende dos tipos de todas essas colunas (por exemplo, você pode precisar usar projeções explícitas).PS. Como restrições exclusivas são impostas por um índice exclusivo, qualquer restrição em índices exclusivos também se aplica a restrições exclusivas:
No entanto, a criação da restrição em uma coluna computada persistente funciona:
Obviamente, a coluna persistente consome o espaço no disco, portanto a abordagem pode ser ruim para uma tabela muito grande. A abordagem de exibição indexada não apresenta esse problema, apenas consome o espaço para o índice , não o espaço para a coluna e o índice calculados .
fonte
Eu acho que você faria muito melhor colocar sua verificação de índice exclusiva em uma coluna computada que é gerada usando
HASHBYTES('MD5', ...)
a combinação de suas 18 colunas.fonte
Encontrei esse problema e meu DBA sênior sugeriu o uso de uma função de verificação de exclusividade. Minhas inserções são relativamente pequenas e pouco frequentes (~ 1.000 linhas, inseridas no início de cada mês) e minha única preocupação é reforçar a exclusividade.
@RBarryYoung, ainda não tenho o representante para comentar, mas tive problemas com a solução HASHBYTES porque um dos meus tipos de dados era uma data e hora e cometi o erro de novato (?) De não fornecer o argumento de estilo opcional ao meu Função CONVERT ao converter para varchar. Sem o estilo, você obtém o seguinte erro ao tentar adicionar as
PERSISTED UNIQUE NONCLUSTERED
restrições:fonte
Você pode combinar alguns dos valores para criar um novo valor exclusivo e armazená-lo, além dos dados atuais.
Crie uma função definida pelo usuário para criar os novos valores e um acionador para preencher o campo quando os dados forem adicionados, para que você não tenha muito mais sobrecarga na manutenção do campo.
A combinação de dois ou três de seus campos colocaria você abaixo do limite de 16.
fonte
Você pode usar um gatilho para
insert
/update
. Faça um agrupamento selecionado por suas colunas com uma cláusula dehaving count(*) > 1
. Se isso voltar não vazio, reverta.fonte
Aqui está o que eu faria. Eu criaria um gatilho AFTER para INSERT, UPDATE que executa uma
ROW_NUMBER ()
função e particiona todas as 18 colunas exclusivas. Se o número máximo de linhas for maior que um, faça aROLLBACK
.fonte