Posso definir uma restrição (lógica) PRIMARY KEY, servida por um NONCLUSTERED INDEX (físico), para que verifique apenas determinados valores da coluna restrita e indexada ou outra coluna na tabela relevante?
E, em caso afirmativo, essa coluna pode ser estabelecida como uma restrição FOREIGN KEY referenciada em outras tabelas?
Estou tentando basicamente ver se posso remover certas linhas de uma tabela pai sem remover essas linhas de uma tabela filha , mas ainda impor o relacionamento para, por exemplo:
IDs > 1000
, ouCreatedDateTime > RemovalDate
.
Por exemplo, você pode ter esse tipo de restrição:
ALTER TABLE MyTable WITH NOCHECK ADD
CONSTRAINT PK_MyTable CHECK (Id > 1000)
mas como você definiria esta coluna como uma PRIMARY KEY fixa com um NONCLUSTERED INDEX?
E posso fazer algo como a seguinte definição:
ALTER TABLE MyTable WITH NOCHECK ADD
CONSTRAINT PK_MyTable CHECK (CreatedOn > '01/01/2010')
mas tem um INDEX para a coluna chamada Id
?
Você não pode ter uma chave primária que funcione apenas para algumas das linhas. Realmente deixaria de ser uma chave primária nesse ponto. Ênfase na Primária.
Você pode jogar com índices filtrados para um índice exclusivo e esse filtro pode estar nos valores que você especificar.
Mas uma chave primária existe para impor a exclusividade, de modo que você não pode tornar apenas parte da tabela parte da chave.
Você pode desabilitar os FKs enquanto faz as correções, pode construir um relacionamento de chave estrangeira em uma tabela existente com
NOCHECK
- mas isso significa que nenhum dos relacionamentos é verificado. Você tem uma chave estrangeira não confiável e alguns dos benefícios que as chaves estrangeiras oferecem, como a eliminação da junção da chave estrangeira, não podem funcionar dessa maneira porque o SQL não garante que sua linha esteja lá ou não.Como alternativa, você pode simplesmente não definir esse relacionamento e lidar com as ramificações. Mas você está basicamente pedindo ao servidor SQL para quebrar a integridade referencial desde o início, fazendo exceções. Se você pudesse transportar essas exceções para uma tabela separada e juntar-se a essa tabela em uma exibição ou algo parecido, você poderia contornar isso e manter o relacionamento na tabela "real" avançando.
Lembre-se, porém: um índice filtrado apenas pode fornecer alguma exclusividade do outro lado do filtro. Isso não aborda FKs ou mesmo o PK. Acho que uma resposta melhor é corrigir o problema com os dados. Mesmo um valor de chave primária -1 para "desconhecido", como é comum em armazéns, seria melhor do que órfãos.
Parece haver alguma confusão. O não
CHECK (Id > 1000)
é uma restrição, é uma restrição.PRIMARY KEY
CHECK
Você pode ter um índice exclusivo parcial (filtrado * ) , se é isso que você procura: (mas isso não é uma restrição de chave primária ou um índice que pode ser usado para a restrição de chave primária). Crie com:
UNIQUE (id) WHERE (id > 1000)
o que significa que todos os
id
valores maiores que 1000 aparecerão apenas uma vez nessa coluna. Todos os outros valores (1000 e inferiores) serão permitidos como duplicados.E da mesma forma para a coluna de data:
o que significa que, para linhas
CratedOn
com 2010 em diante, osid
valores serão exclusivos. Todas as outras linhas (que têmCreatedOn
em 2009 e anteriores ouNULL
) serão ignoradas para esse índice exclusivo. Portanto, você pode ter valores duplicadosid
, desde que todos, exceto um, não correspondam àWHERE
condição do índice.Esses índices não serão agrupados, é claro - todos os índices parciais são.
E eles não podem ser usados como alvos para
FOREIGN KEY
restrições.*: Consulte as páginas de índices
CREATE INDEX
e Fileterd no MSDN ou detalhes de uso e vantagens.Sobre eles "por que não podemos referenciar um índice parcial?":
Isso é o que diz o padrão SQL e como ele é implementado no SQL Server. Uma restrição FK deve fazer referência a uma coluna (ou colunas) de uma tabela. Não é um índice. Um índice parcial por definição contém uma parte dos valores que aparecem na coluna, não todos eles.
Uma pergunta relacionada que fiz há algum tempo: Existem SGBDs que permitem uma Chave Estrangeira que Referencia uma View (e não apenas tabelas base)? .
Não há nenhum problema inerente ao modelo relacional que impeça a definição de tais FKs. Mas o SQL (comitê e os vários DBMS) não adicionou isso como um recurso.