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.
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.
Uma chave estrangeira destina-se a restringir os dados. ou seja, impor integridade referencial. É isso. Nada mais.
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.
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.
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.
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.
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.
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.
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 para
NATURAL JOIN
), eu uso o SQL Prompt no Management Studio: ao escrever umINNER JOIN
seu InteliSense sugereON
clá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.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.
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.
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.
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!)
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...
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?
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.