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 / 15147
Accepted
Tiddo
Tiddo
Asked: 2012-03-16 16:16:57 +0800 CST2012-03-16 16:16:57 +0800 CST 2012-03-16 16:16:57 +0800 CST

Por que as correspondências de chave primária/chave estrangeira não são usadas para junções?

  • 772

Até onde eu pude descobrir, muitos DBMSs (por exemplo, mysql, postgres, mssql) usam combinações fk e pk apenas para restringir as alterações nos dados, mas raramente são usados ​​nativamente para selecionar automaticamente as colunas a serem unidas (como a junção natural faz com nomes). Por que é que? Se você já definiu um relacionamento entre 2 tabelas com um pk/fk, por que o banco de dados não consegue descobrir que, se eu juntar essas tabelas, quero juntá-las nas colunas pk/fk?

EDIT: para esclarecer um pouco:

suponha que eu tenha uma tabela1 e uma tabela2. table1 one tem uma chave estrangeira na coluna a, que faz referência à chave primária na table2, a coluna b. Agora se eu juntar essas tabelas, terei que fazer algo assim:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

No entanto, eu já defini usando minhas chaves que table1.a faz referência a table2.b, então me parece que não deve ser difícil fazer um sistema DBMS usar automaticamente table1.a e table2.b como colunas de junção, tal que se pode simplesmente usar:

SELECT * FROM table1
AUTO JOIN table2

No entanto, muitos DBMS parecem não implementar algo assim.

sql-server mysql
  • 11 11 respostas
  • 33375 Views

11 respostas

  • Voted
  1. Best Answer
    Sjoerd
    2012-03-16T19:07:49+08:002012-03-16T19:07:49+08:00

    Em muitos casos, há mais de uma maneira de unir duas tabelas; Veja as outras respostas para muitos exemplos. Claro, pode-se dizer que seria um erro usar a 'junção automática' nesses casos. Então restaria apenas um punhado de casos simples em que ele pode ser usado.

    No entanto, há uma desvantagem grave! As consultas que estão corretas hoje podem se tornar um erro amanhã apenas adicionando um segundo FK à mesma tabela!

    Deixe-me dizer novamente: adicionando colunas, as consultas que não usam essas colunas podem passar de 'corretas' para 'erros'!

    Isso é um pesadelo de manutenção, que qualquer guia de estilo sensato proibiria o uso desse recurso. A maioria já proíbe select *pelo mesmo motivo!

    Tudo isso seria aceitável, se o desempenho fosse aprimorado. No entanto, esse não é o caso.

    Resumindo, esse recurso pode ser usado apenas em um conjunto limitado de casos simples, não aumenta o desempenho e a maioria dos guias de estilo proibiria seu uso de qualquer maneira.

    Portanto, não é surpreendente que a maioria dos fornecedores de banco de dados opte por gastar seu tempo em coisas mais importantes.

    • 37
  2. Lord Tydus
    2012-03-16T18:13:58+08:002012-03-16T18:13:58+08:00

    Uma chave estrangeira destina-se a restringir os dados. ou seja, impor integridade referencial. É isso. Nada mais.

    1. Você pode ter várias chaves estrangeiras para a mesma tabela. Considere o seguinte onde uma remessa tem um ponto inicial e um ponto final.

      table: USA_States
      StateID
      StateName
      
      table: Shipment
      ShipmentID
      PickupStateID Foreign key
      DeliveryStateID Foreign key
      

      Você pode querer participar com base no estado de coleta. Talvez você queira participar no estado de entrega. Talvez você queira realizar 2 junções para ambos! O mecanismo sql não tem como saber o que você quer.

    2. Frequentemente, você cruzará valores escalares de junção. Embora os escalares sejam geralmente o resultado de cálculos intermediários, às vezes você terá uma tabela de propósito especial com exatamente 1 registro. Se o mecanismo tentasse detectar uma chave estrangeira para a junção... não faria sentido porque as junções cruzadas nunca correspondem a uma coluna.

    3. Em alguns casos especiais, você se unirá em colunas onde nenhuma delas é exclusiva. Portanto, a presença de um PK/FK nessas colunas é impossível.

    4. Você pode pensar que os pontos 2 e 3 acima não são relevantes, pois suas perguntas são sobre quando existe uma única relação PK/FK entre as tabelas. No entanto, a presença de um único PK/FK entre as tabelas não significa que você não possa ter outros campos para unir além do PK/FK. O mecanismo sql não saberia em quais campos você deseja ingressar.

    5. Digamos que você tenha uma tabela "USA_States" e 5 outras tabelas com um FK para os estados. As tabelas "cinco" também possuem algumas chaves estrangeiras entre si. O mecanismo sql deve unir automaticamente as tabelas "cinco" com "USA_States"? Ou deve juntar os "cinco" entre si? Ambos? Você pode configurar os relacionamentos para que o mecanismo sql entre em um loop infinito tentando juntar as coisas. Nesta situação é impossível para o motor sql adivinhar o que você quer.

    Em resumo: PK/FK não tem nada a ver com junções de tabelas. São coisas separadas e não relacionadas. É apenas um acidente da natureza que você costuma juntar nas colunas PK/FK.

    Você gostaria que o mecanismo sql adivinhasse se é uma junção completa, esquerda, direita ou interna? Eu não acho. Embora isso fosse sem dúvida um pecado menor do que adivinhar as colunas para se juntar.

    • 28
  3. onedaywhen
    2012-03-17T05:15:48+08:002012-03-17T05:15:48+08:00

    o conceito de "joinability". As relações r1e r2são juntáveis ​​se e somente se os atributos com o mesmo nome forem do mesmo tipo... esse conceito se aplica não apenas à junção como tal, mas também a várias outras operações [como união].

    SQL e teoria relacional: como escrever código SQL preciso por data CJ

    O SQL padrão já possui esse recurso, conhecido como NATURAL JOIN, e foi implementado no mySQL.

    Embora sua sugestão não seja tão digna, parece razoável. Com o SQL Server (que não tem suporte paraNATURAL JOIN ), eu uso o SQL Prompt no Management Studio: ao escrever um INNER JOINseu InteliSense sugere ONcláusulas baseadas em nomes de atributos comuns e chaves estrangeiras e acho muito útil. No entanto, não tenho grande desejo de ver um novo tipo de junção SQL (padrão) para isso.

    • 12
  4. James Anderson
    2012-03-16T18:08:47+08:002012-03-16T18:08:47+08:00

    SQL veio em primeiro lugar!

    As restrições de Chaves Estrangeiras e Chaves Estrangeiras vieram mais tarde e são essencialmente uma otimização para aplicativos de estilo "transação".

    Bancos de dados relacionais foram originalmente concebidos como um método de aplicação de consultas complexas em conjuntos de dados de uma forma que era matematicamente demonstrável usando álgebra relacional. IE para um determinado conjunto de dados e uma determinada consulta, sempre há uma única resposta correta.

    Bancos de dados relacionais percorreram um longo caminho desde então, e seu uso primário como camada de persistência para sistemas transacionais não era o que CODD et. todos previstos.

    No entanto, o corpo de padrões ANSI para todos os seus objetivos conflitantes e políticas de fornecedores sempre se esforçou para preservar as propriedades "matematicamente comprováveis" do SQL.

    Se você permitisse que o banco de dados inferisse as propriedades de junção de dados de chave estrangeira "ocultos", perderia essa propriedade (considere a ambiguidade se houver mais de um conjunto de chaves estrangeiras definido).

    Além disso, um programador lendo o SQL não saberia necessariamente quais chaves estrangeiras estavam atualmente definidas para as duas tabelas e precisaria examinar o esquema do banco de dados para descobrir o que a consulta estava fazendo.

    • 10
  5. Morons
    2012-03-16T16:24:23+08:002012-03-16T16:24:23+08:00

    Você pode estar operando em uma suposição falsa. Você diz 'até onde pode descobrir', mas não fornece nenhuma prova empírica ou evidencial. Se o pk ou fk for o melhor índice para uma consulta, ele será usado. Não sei por que você está vendo isso, mas meu palpite é de consultas mal formadas.


    Edite agora que a pergunta foi totalmente reescrita: O caso que você está descrevendo seria apenas para um conjunto muito pequeno de consultas. E se houver 12 tabelas unidas? E se não houver FKs... Mesmo se houvesse uma junção padrão, eu ainda sempre especificaria a junção apenas para facilitar a leitura. (Eu não quero ter que olhar para os dados e depois tentar descobrir o que está sendo unido)

    Algumas ferramentas de consulta realmente fazem uma junção automática para você e permitem que você remova ou edite a junção. Acho que o Query Builder do MS Access faz isso.

    Por fim, o padrão ANSII afirma que a junção deve ser especificada. Isso é motivo suficiente para não permitir.

    • 7
  6. BillThor
    2012-03-16T17:16:22+08:002012-03-16T17:16:22+08:00

    Embora você tenha definido um relacionamento de chave estrangeira, isso não significa que é assim que você deseja unir as tabelas em todas as consultas. É o método mais provável para juntar as tabelas, mas há casos em que não está correto.

    • Você pode querer usar um produto cartesiano das duas tabelas ou parte delas para algum propósito.
    • Pode haver outros campos nos quais você pode participar para outra finalidade.
    • Se você estiver unindo três ou mais tabelas, uma das tabelas pode estar relacionada a duas ou mais tabelas. Nesse caso, geralmente apenas um dos possíveis relacionamentos FK pode ser apropriado na consulta.
    • 7
  7. Ian Ringrose
    2012-03-17T01:58:18+08:002012-03-17T01:58:18+08:00

    Há muitas razões pelas quais o banco de dados não pode fazer isso com segurança, incluindo o fato de que adicionar/remover chaves estrangeiras alterará o significado de consultas pré-escritas, incluindo consultas no código-fonte do aplicativo. A maioria dos bancos de dados também não tem um bom conjunto de Chaves Estrangeiras que cobrem todas as junções possíveis que você provavelmente deseja fazer. Também para melhor ou para valer a pena, as chaves estrangeiras geralmente são removidas para acelerar os sistemas e não podem ser usadas em tabelas que são carregadas na ordem "errada" do arquivo.

    No entanto, não há razão para que uma ferramenta de design de consulta ou o editor de texto não possa concluir automaticamente uma junção com a ajuda de Chaves estrangeiras da mesma maneira que eles fornecem intellisense no nome da coluna. Você pode editar a consulta se a ferramenta errar e salvar uma consulta completamente definida. Essa ferramenta também pode usar a convenção de nomear colunas de Chaves Estrangeiras pelo nome da tabela “pai” e colunas com o mesmo nome na tabela pai/filho etc.

    (Minha esposa ainda não consegue entender a diferença entre Management Studio e Sql Server e fala sobre iniciar o sql server quando ela inicia o Management Studio!)

    • 4
  8. jmoreno
    2012-03-16T19:56:32+08:002012-03-16T19:56:32+08:00

    A razão é que existe o LANGUAGE e, em seguida, existem os princípios subjacentes. A linguagem é esparsa e carece de muitos recursos que você esperaria ver em uma linguagem de propósito geral. Isso simplesmente acontece de ser um bom recurso que não foi adicionado ao idioma e provavelmente não será. Não é uma língua morta, então há alguma esperança, mas eu não seria otimista.

    Como outros apontaram, algumas implementações usam uma extensão onde join (coluna) une duas tabelas com base em um nome de coluna comum, que é um pouco semelhante. Mas não é amplamente difundido. Observe que essa extensão é diferente da SELECT * FROM employee NATURAL JOIN department;sintaxe que não inclui uma maneira de especificar quais colunas usar. Nenhum deles depende de um relacionamento entre as tabelas, o que as torna não confiáveis ​​(a sintaxe de junção natural mais do que a extensão).

    Não há nenhum obstáculo fundamental para "tabela de junção interna no PKFK", onde PKFK é uma palavra-chave que significa "o relacionamento de chave estrangeira definido entre as duas tabelas", pode haver problemas com vários fk para a mesma tabela, mas isso pode simplesmente causar um erro. A questão é se as pessoas que estão projetando a linguagem consideram que a) uma boa ideia eb) melhor trabalhar do que alguma outra mudança de linguagem...

    • 3
  9. philipxy
    2017-10-15T13:34:00+08:002017-10-15T13:34:00+08:00

    A junção natural "automaticamente" une a igualdade de colunas comuns, mas você só deve escrever isso se for o que deseja com base nos significados da tabela e no resultado desejado. Não há "automaticamente" saber como duas tabelas "devem" ser unidas ou de qualquer outra forma qualquer tabela "deve" aparecer em uma consulta. Não precisamos conhecer restrições para consultar. Sua presença significa apenas que as entradas podem ser limitadas e, consequentemente, a saída também. Você pode definir algum tipo de operador join_on_fk_to_pk que une "automaticamente" por restrições declaradas; mas se você quiser que o significado da consulta permaneça o mesmo se apenas as restrições forem alteradas, mas não os significados da tabela, será necessário alterar essa consulta para não usar as novas restrições declaradas.já deixa o mesmo significado apesar de qualquer alteração de restrição .

    Quais restrições são mantidas (incluindo PKs, FKs, UNIQUE e CHECK) não afetam o significado das tabelas. É claro que, se os significados da tabela mudarem, as restrições poderão mudar. Mas se as restrições mudarem, isso não significa que as consultas devam mudar.

    Não é necessário conhecer restrições para consultar. Conhecer as restrições significa que podemos usar outras expressões que, sem a restrição, não retornariam a mesma resposta. Por exemplo, esperando via UNIQUE que uma tabela tenha uma linha, para que possamos usá-la como escalar. Essas consultas podem ser interrompidas se a restrição foi assumida, mas não declarada. Mas declarar uma restrição que a consulta não assumiu não pode quebrá-la.

    Existe alguma regra prática para construir uma consulta SQL a partir de uma descrição legível por humanos?

    • 3
  10. JeffO
    2012-03-16T19:42:00+08:002012-03-16T19:42:00+08:00

    Se a omissão da cláusula ON seguir os campos com base na integridade referencial, como você faria um produto cartesiano?

    Edit: usando AUTO As vantagens disso é um pouco menos de digitação e você não precisa saber como eles são unidos ou lembrar de uma junção complicada. Se o relacionamento mudar, ele será tratado automaticamente, mas isso raramente acontece, exceto no início do desenvolvimento.

    O que você precisa fazer agora é decidir se todas as suas junções AUTO são válidas durante uma alteração de relacionamento para corresponder à intenção de sua instrução select.

    • 2

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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