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 / 160918
Accepted
SQLserving
SQLserving
Asked: 2017-01-13 12:58:11 +0800 CST2017-01-13 12:58:11 +0800 CST 2017-01-13 12:58:11 +0800 CST

Processo de Chave Estrangeira

  • 772

Estou tentando entender como as chaves estrangeiras funcionariam de uma perspectiva de processamento interno (estou usando o SQLServer). Em outras palavras, como uma tabela seria afetada pela adição de uma chave estrangeira?

Digamos que eu tenha duas tabelas (PK são não nulos):

TableA : PK Student_ID, StudentName, StudentAddress
TableB : PK Books_ID, FK Student_ID, Books_IssueMonth

select Student_ID from TableB where Books_IssueMonth=January;

Quando eu executo uma instrução sql ao TableBchamar Student_ID, o sistema é informado para primeiro procurá-lo TableAe, em seguida, apontar para o índice clusterizado ( Books_ID) em TableB?

Seriam buscas de duas mesas?

ou seria uma busca na TableA e scan na TableB?

database-design foreign-key
  • 2 2 respostas
  • 119 Views

2 respostas

  • Voted
  1. Best Answer
    joanolo
    2017-01-13T13:53:52+08:002017-01-13T13:53:52+08:00

    Uma restrição de chave estrangeira na TableB tem efeito em três níveis (pelo menos).

    1. Quando você INSERT INTO TableBencontra uma linha em que Student_ID não é nulo, o valor de Student_ID é procurado na TabelaA. Se não estiver lá, a inserção falhará (a linha não será inserida no banco de dados); se a inserção fizer parte de uma transação maior, a própria transação falhará. UPDATEs da TableBcoluna envolvente Student_IDse comportam de maneira semelhante (o novo valor para Student_ID é procurado na TabelaA).

    2. Quando você UPDATE TableA SET Student_ID=<value>ou DELETE FROM TableAqualquer linha, o valor antigo da coluna Student_IDserá pesquisado na TabelaB. Isso incorre em alguma penalidade de desempenho (especialmente se a coluna não estiver indexada na TableB, mas o que normalmente é chamado de foreign key covering index). Se o valor for encontrado então: se a restrição FK não especificou o que fazer em UPDATE ou DELETE, o UPDATE ou INSERT falhará, porque violaria a restrição. Se o FK especificar o que fazer em UPDATE e/ou DELETE, a ação especificada será executada. Se a condição for CASCADEesta, poderá disparar UPDATES/DELETEs em tabelas referenciadas pela tabela referenciada, recursivamente.

    3. Em a SELECT, uma restrição FK não terá nenhuma penalidade . Pode ter alguns efeitos benéficos para o planejador do banco de dados. A condição TableB.Student_ID IS NULL OR TableB.Student_ID in (SELECT Student_ID FROM TableA)é um fato conhecido pelo planejador, e isso pode ser usado com alguma vantagem (por exemplo, se tal condição existir em uma cláusula WHERE, ela pode ser substituída por uma constante TRUE, facilitando o processamento). Outra otimização seria converter a TableB LEFT JOIN TableA USING (Student_ID)em um INNER JOIN, se Student_ID for conhecido como não nulo, porque o planejador sabe que todas as linhas serão encontradas na TabelaA. Quanto lucro os diferentes planejadores obterão desse conhecimento dependerá fortemente da implementação.

    Selecionar linhas de TableB(se TableAtambém não for especificado na cláusula FROM) não terá nenhum efeito na busca Student_IDem TableA. As restrições de chave estrangeira são aplicadas quando os dados são inseridos ou atualizados e, em seguida, conhecidos como retidos quando os dados são selecionados.


    NOTA : Uma restrição FK pode especificar o que fazer quando o Student_ID pai for UPDATED ou DELETED. A sintaxe específica pode ter pequenas variações, mas é tipicamente ON {UPDATE|DELETE} {RESTRICT|NO ACTION|SET DEFAULT|SET NULL|CASCADE}. Verifique como isso funciona para PostgreSQL , MySQL , Oracle e SQL Server .

    • 4
  2. Walter Mitty
    2017-01-13T20:51:16+08:002017-01-13T20:51:16+08:00

    para a instrução SELECT específica sobre a qual você perguntou, não há motivo para a consulta ir para a Tabela A, pois a consulta menciona apenas a Tabela B. Pelo menos isso é verdade para qualquer produto de banco de dados com o qual trabalhei. Você não disse com qual produto de banco de dados você trabalha.

    A questão sobre qual estratégia ele usaria para encontrar todas as linhas onde Books_IssueMonth = "January", isso dependeria de quais índices existem na tabela. Se houver um índice na coluna em questão, o otimizador de consulta quase certamente usará esse índice para localizar as linhas relevantes em alguns acessos ao disco. Se não houver índice na coluna em questão, a consulta teria que fazer uma varredura completa da tabela na TabelaB, o que poderia acarretar milhões de acessos ao disco se houvesse linhas suficientes na TabelaB.

    A questão se torna mais interessante é você perguntar sobre um select que une TableA e TableB. Você não perguntou sobre isso. nesse caso, você precisará da coluna StudentID na TabelaB, mesmo que não a declare como FK.

    No que diz respeito a ter uma coluna como StudentID que funciona como uma chave estrangeira, mas não é declarada com uma restrição FK, geralmente é uma má ideia, pelos motivos descritos na resposta de joanolo.

    • 2

relate perguntas

  • Os índices filtrados podem ajudar a melhorar as consultas baseadas em uma hora inserida ou isso deve ser evitado?

  • Qual é a diferença entre os tipos de dados MySQL VARCHAR e TEXT?

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

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