Tanto quanto pude descobrir, muitos DBMSs (por exemplo, mysql, postgres, mssql) usam combinações fk e pk apenas para restringir alterações nos dados, mas raramente são usados de forma nativa para selecionar automaticamente colunas para ingressar (como a junção natural faz com nomes). Por que é que? Se você já definiu um relacionamento entre duas tabelas com um pk / fk, por que o banco de dados não pode descobrir que, se eu ingressar nessas tabelas, quero juntá-las nas colunas pk / fk?
EDIT: para esclarecer isso um pouco:
suponha que eu tenho uma tabela1 e uma tabela2. A tabela 1 tem uma chave estrangeira na coluna a, que faz referência à chave primária na tabela 2, a coluna b. Agora, se eu ingressar nessas 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, portanto, parece-me que não deve ser difícil criar um sistema DBMS usando automaticamente table1.a e table2.b como as colunas de junção, de modo que alguém possa simplesmente usar:
SELECT * FROM table1
AUTO JOIN table2
No entanto, muitos DBMS não parecem implementar algo assim.
fonte
NATURAL JOIN
(é por isso que geralmente as evito), mas não acho que isso deva significar que um dbms não possa implementar uma maneira automática de associar tabelas com base em chaves estrangeiras.AUTO JOIN mytable THROUGH myrelation
, seria muito bom.InnerJoin(SRC_TABLE.rDEST_TABLE.REL_NAME_F01)
Uma chave estrangeira deve restringir os dados. ou seja, impor integridade referencial. É isso aí. Nada mais.
Você pode ter várias chaves estrangeiras na mesma tabela. Considere o seguinte em que uma remessa tem um ponto inicial e um ponto final.
Você pode querer participar com base no estado de recebimento. Talvez você queira ingressar no estado de entrega. Talvez você queira realizar 2 junções para ambos! O mecanismo sql não tem como saber o que você deseja.
Você geralmente cruza valores escalares de junção. Embora os escalares geralmente sejam o resultado de cálculos intermediários, às vezes você terá uma tabela de finalidade 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ê ingressará em colunas nas quais nenhuma é única. 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 é sobre quando há É a / relacionamento único PK FK entre tabelas. No entanto, a presença de PK / FK único entre as tabelas não significa que você não pode ter outros campos para ingressar 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 mais 5 tabelas com um FK para os estados. As "cinco" tabelas também têm algumas chaves estrangeiras entre si. O mecanismo sql deve ingressar automaticamente nas "cinco" tabelas com "USA_States"? Ou deveria juntar os "cinco" um ao outro? Ambos? Você pode configurar os relacionamentos para que o mecanismo sql entre em um loop infinito tentando juntar as coisas. Nessa situação, é impossível que o mecanismo sql adivinhe o que você deseja.
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 participar das colunas PK / FK.
Deseja que o mecanismo sql adivinhe se é uma junção completa, esquerda, direita ou interna? Acho que não. Embora isso possa ser um pecado menor do que adivinhar as colunas para se juntar.
fonte
SQL e teoria relacional: como escrever código SQL preciso por data de 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 possui suporte
NATURAL JOIN
), uso o SQL Prompt no Management Studio: ao escrever umINNER JOIN
InteliSense, sugiroON
cláusulas com base em nomes de atributos comuns e chaves estrangeiras, e acho muito útil. No entanto, não desejo muito ver um novo tipo de associação SQL (padrão) para isso.fonte
SQL veio primeiro!
As restrições de Chaves estrangeiras e Chaves estrangeiras vieram mais tarde e são essencialmente uma otimização para aplicativos no estilo "transação".
Os bancos de dados relacionais foram originalmente concebidos como um método de aplicação de consultas complexas em conjuntos de dados de uma maneira que fosse matematicamente comprovável usando álgebra relacional. IE para um determinado conjunto de dados e uma determinada consulta, há sempre uma única resposta correta.
Os bancos de dados relacionais percorreram um longo caminho desde então, e o uso primário como camada de persistência para sistemas transacionais não foi o que CODD et. tudo previsto.
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 propriedades "prováveis matematicamente" do SQL.
Se você permitisse que o banco de dados inferisse as propriedades de junção dos dados de chave estrangeira "ocultos", você perderia essa propriedade (considere a ambiguidade se houvesse mais de um conjunto de chaves estrangeiras definido).
Além disso, um programador que lê o SQL não saberia necessariamente quais chaves estrangeiras foram definidas atualmente para as duas tabelas e precisaria examinar o esquema do banco de dados para descobrir o que a consulta estava fazendo.
fonte
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 ingressar nas tabelas, mas há casos em que não está correto.
fonte
Você pode estar operando com uma suposição falsa. Você diz 'até onde pode descobrir', mas não fornece nenhuma prova empírica ou probatória. Se o pk ou o fk forem o melhor índice para uma consulta, ele será usado. Não sei por que você está vendo isso, mas meu palpite é 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 Registradas? E se não houver FKs .... Mesmo se houvesse uma associação padrão, eu ainda especificaria sempre a associação apenas para facilitar a leitura. (Eu não quero ter que olhar para os dados e tentar descobrir em que está sendo juntado)
Algumas ferramentas de consulta, na verdade, fazem uma associação automática para você e permitem remover ou editar a associação. Acho Query Builder do MS Access faz isso.
Por fim, o padrão ANSII afirma que a associação deve ser especificada. Essa é a razão suficiente para não permitir.
fonte
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 possui um bom conjunto de chaves estrangeiras que cobrem todas as junções possíveis que você provavelmente deseja. Também para melhor ou para o melhor, as Chaves Estrangeiras são frequentemente removidas para acelerar os sistemas e não podem ser usadas em tabelas 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 consiga concluir automaticamente uma junção com a ajuda de Chaves estrangeiras da mesma maneira que elas fornecem inteligência no nome da coluna. Você pode editar a consulta se a ferramenta estiver errada e salvar uma consulta completamente definida. Essa ferramenta também pode ser útil para 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 o Management Studio e o Sql Server e fala sobre como iniciar o sql server quando inicia o management studio!)
fonte
A junção natural "automaticamente" se une à igualdade de colunas comuns, mas você deve escrever apenas se é isso 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 a serem consultadas. 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 "junte-se" automaticamente por restrições declaradas; mas se você quiser que o significado da consulta permaneça o mesmo, se apenas as restrições mudarem, 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 significado da mesma forma, apesar de qualquer alteração de restrição .
As restrições mantidas (incluindo PKs, FKs, UNIQUE & CHECK) não afetam o significado das tabelas. Obviamente, 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 devem mudar.
Não é necessário conhecer restrições a serem consultadas. Conhecer restrições significa que podemos usar outras expressões que, sem a restrição de retençã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 a consulta SQL a partir de uma descrição legível por humanos?
fonte
O motivo é que existe o IDIOMA e os principais subjacentes. O idioma é escasso e carece de muitos recursos que você esperaria ver em um idioma de uso geral. Isso simplesmente é um recurso interessante 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 ficaria otimista.
Como outros já apontaram, algumas implementações usam uma extensão em que join (coluna) une duas tabelas com base em um nome de coluna comum, que é um pouco semelhante. Mas não é amplamente divulgado. 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. Também não confie em um relacionamento entre as tabelas, o que as torna não confiáveis (a sintaxe de junção natural é maior que a extensão).Não há obstáculo fundamental para "tabela de junção interna no PKFK", em que PKFK é uma palavra-chave que significa "o relacionamento de chave estrangeira definido entre as duas tabelas"; pode haver problemas com vários fk na mesma tabela, mas isso pode simplesmente causar um erro. A questão é: as pessoas que projetam o idioma consideram que: a) uma boa idéia eb) melhor trabalhar do que alguma outra mudança de idioma ...
fonte
Se a omissão da cláusula ON seguir os campos com base na integridade referencial, como você faria um produto cartesiano?
Editar: usando AUTO As vantagens disso são um pouco menos de digitação e você não precisa saber como elas são unidas ou se lembrar de uma união complicada. Se o relacionamento mudar, ele será tratado automaticamente, mas isso raramente acontece, exceto no desenvolvimento inicial.
O que você precisa fazer agora é decidir se todas as suas junções AUTO serão mantidas durante uma alteração no relacionamento para corresponder à intenção da sua declaração de seleção.
fonte
Partes do motivo são:
1 - em teoria, você pode juntar tabelas em colunas arbitrárias a partir das duas tabelas. Embora isso não seja uma prática comum, é válido. Lembre-se de que o SQL é como uma linguagem de programação, ele não entende quais informações estão nas colunas de curso e nomes; para o SQL, não significa muito a esse respeito.
2 - Existem diferentes tipos de junções (esquerda, direita, interna) - as junções internas são apenas 1 delas.
3 - O padrão SQL pode ser guiado pelo princípio de ser uma linguagem de nível inferior que permite aos dialetos de nível superior formar inteligência usando-a. A comparação é um pouco mais clara se você pensar em um idioma de quarta geração vs. um idioma de terceira geração. De fato, uma ferramenta que usei, o IEF, permitiu que você escrevesse algo assim:
Em resumo, sua sugestão é interessante e pode ser implementada como parte do padrão ou como um procedimento armazenado (o padrão seria uma Junção Interna).
fonte
Bom, eu acredito que você está completamente certo, o SQL nesse tópico é bastante idiota , e eu lembro de ter pensado o mesmo que você pensava sobre chaves estrangeiras enquanto aprendia SQL há dez anos.
Ok, dado que, finalmente tive que passar no exame; e para passar, eu tive que deixar ir . O SQL é mais um naufrágio do que qualquer um pode admitir, seu caminho de padronização é um desastre completo e algumas implementações são ameaçadoras . Ainda assim, é bastante útil, em geral. (Eu não sou um Lududita K / V)
Chaves estrangeiras, então ... não são tão úteis assim. Eles são um conceito importante no modelo relacional , ok, mas o recurso SQL com o mesmo nome não se compara bem.
Diga-lo direto: não use esse recurso SQL chamado
Foreign Key
em tudo , até atingir algum grande sistema com problemas de desempenho. Informar explicitamente ao mecanismo qual campo é uma chave estrangeira e qual não é é usado apenas para indexação e é invisível para o usuário do banco de dados.Isso é enganador?
Sim.
Eles vão torná-lo mais poderoso agora, depois de 30 anos de pessoas sendo enganadas?
Sem chance.
Ignorando completamente chaves estrangeiras até necessário ... corrigiu o SQL para mim?
Sim!
E por que diabos tudo isso aconteceu em primeiro lugar?
Bem, o recurso que chamamos de chaves estrangeiras foi adicionado posteriormente ao SQL; SQL é um padrão que evoluiu ao longo do tempo, de baixo para cima. Os fornecedores implementaram recursos ridículos, enquanto os organismos padrão se enfrentaram.
Chaves estrangeiras, como dito, onde apenas destinavam-se à indexação e não havia construção JOIN disponível. (junta-se onde as consultas são feitas
SELECT
, asJOIN
consultas são bastante recentes e destinam-se apenas àSELECT
funcionalidade de alias ). Eles provavelmente consideraram que chamar esse sinalizador de indexaçãoFOREIGN KEY
foi um truque de nomeação inteligente sobre os conceitos da teoria do banco de dados relacional.fonte