AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 157515
Accepted
John
John
Asked: 2016-12-08 12:13:31 +0800 CST2016-12-08 12:13:31 +0800 CST 2016-12-08 12:13:31 +0800 CST

Uma restrição PRIMARY KEY (com um NONCLUSTERED INDEX) pode verificar apenas determinados valores?

  • 772

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, ou
  • CreatedDateTime > 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?

sql-server sql-server-2008
  • 2 2 respostas
  • 841 Views

2 respostas

  • Voted
  1. Mike Walsh
    2016-12-08T12:24:22+08:002016-12-08T12:24:22+08:00

    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.

    • 6
  2. Best Answer
    ypercubeᵀᴹ
    2016-12-08T12:26:09+08:002016-12-08T12:26:09+08:00

    Parece haver alguma confusão. O nãoCHECK (Id > 1000) é uma restrição, é uma restrição.PRIMARY KEYCHECK

    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)

    CREATE UNIQUE INDEX Id_more_than_1000_PUQ
      ON MyTable (id) WHERE (id > 1000) ;
    

    o que significa que todos os idvalores 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:

    CREATE UNIQUE INDEX Id_when_created_on_2010_and_after_PUQ
      ON MyTable (id) WHERE (CreatedOn >= '20100101') ;
    

    o que significa que, para linhas CratedOncom 2010 em diante, os idvalores serão exclusivos. Todas as outras linhas (que têm CreatedOnem 2009 e anteriores ou NULL) serão ignoradas para esse índice exclusivo. Portanto, você pode ter valores duplicados id, desde que todos, exceto um, não correspondam à WHEREcondiçã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 KEYrestrições.

    *: Consulte as páginas de índices CREATE INDEXe 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.

    • 6

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve