No Learn SQL the Hard Way (exercício seis) , o autor apresenta a seguinte consulta:
SELECT pet.id, pet.name, pet.age, pet.dead
FROM pet, person_pet, person
WHERE
pet.id = person_pet.pet_id AND
person_pet.person_id = person.id AND
person.first_name = "Zed";
e depois continua dizendo que:
Na verdade, existem outras maneiras de fazer com que esses tipos de consultas funcionem chamados "junções". Estou evitando esses conceitos por enquanto, porque eles são incrivelmente confusos. Apenas se atenha a essa maneira de ingressar nas tabelas por enquanto e ignore as pessoas que tentam dizer a você que isso é de alguma forma mais lento ou "classe baixa".
Isso é verdade? Por que ou por que não?
Respostas:
Com a abordagem do autor, o ensino de OUTER JOINs será muito mais difícil. A cláusula ON de INNER JOIN nunca foi alucinante para mim, como muitas outras coisas. Talvez seja porque nunca aprendi da maneira antiga. Eu gostaria de pensar que há uma razão pela qual nos livramos dela e não era para ser convencido e chamar esse método de classe baixa.
É verdade no cenário muito restrito que o autor criou:
Como parte de uma progressão de ensino, acho que é mais fácil decompô-la e ter uma progressão natural:
Os conceitos de união e filtragem de tabelas não são realmente os mesmos. Aprender a sintaxe correta agora terá mais carry-over quando você aprender as junções externas a menos que o autor tem a intenção de ensinar ultrapassadas / coisas obsoletas, como:
*= or =*
.fonte
*=
ou=*
indicava associações externas esquerda ou direita, outro que eu usei apenas suportou associações externas esquerdas usando um|=
operador.+=
ou talvez tenha sido=+
. Eu acredito que*=
era Transact-SQL (Sybase e mais tarde MS-SQL). Ainda assim, bom argumento.WHERE
cláusula. (Eu já ouvi essa referida como uma teta juntar-se , mas eu não tenho certeza se isso é correto.)O fato de ser mais lento depende do Query Optimizer e de como ele otimiza a consulta (o que você escreve não é realmente o que é executado). No entanto, o grande problema dessa citação é que ela ignora completamente o fato de que existem diferentes tipos de junções que operam de maneira completamente diferente. Por exemplo, o que está sendo dito é (teoricamente) verdadeiro para
inner joins
, mas não é válido paraouter joins
(left joins
eright joins
).fonte
INNER JOIN
ouLEFT OUTER JOIN
. Eles não são "insanamente confusos". O SQL pode ficar incrivelmente confuso, mas este não é um exemplo disso.O autor apresenta um caso simples em que a sintaxe antiga ou nova pode ser usada. Não concordo com sua afirmação de que as junções são incrivelmente confusas, porque a junção de tabelas é um conceito fundamental de consulta SQL. Portanto, talvez o autor deva ter passado algum tempo explicando como o JOINS funciona antes de proferir uma declaração opinativa, bem como fazer um exemplo de consulta de tabela múltipla.
Deve-se usar a sintaxe mais recente. O principal argumento para isso é que sua consulta terá:
Usando o estilo antigo, os critérios de junção e filtro são combinados, o que, em casos mais complexos, pode causar confusão.
Além disso, pode-se obter um produto cartesiano esquecendo um critério de junção na cláusula de filtro:
usando a sintaxe mais antiga.
O uso da sintaxe mais recente também especifica como a junção deve ocorrer, o que é importante se você deseja um INTERNO, ESQUERDO EXTERIOR etc., para que seja mais explícito em relação à sintaxe JOIN, que IMHO aumenta a legibilidade para aqueles que não estão familiarizados com as tabelas de junção.
fonte
Não deveria haver, o analisador de consultas deve gerar uma representação interna equivalente para consultas equivalentes, independentemente de como elas sejam gravadas. O autor está apenas usando a sintaxe pré-SQL-92, e é por isso que ele menciona que pode ser vista como "antiquada" ou "classe baixa". Internamente, o analisador e o otimizador devem gerar o mesmo plano de consulta.
fonte
Eu aprendi SQL dessa maneira, incluindo o
*=
sintaxe para junções externas. Para mim, foi muito intuitivo, pois todas as relações tiveram igual precedência e fizeram um trabalho melhor ao configurar consultas como uma série de perguntas: O que você quer? De onde você os quer? Quais você quer?Ao fazer a
join
sintaxe, interrompe o processo de pensamento em relação às relações com mais força. E, pessoalmente, acho o código muito menos legível com as tabelas e relações entrelaçadas.Pelo menos no MSSQL, não há diferença significativa no desempenho das consultas, supondo que você use a mesma ordem de junção. Dito isto, há um problema claro e enorme com o aprendizado (e o uso) de SQL dessa maneira. Se você esquecer uma de suas relações, obterá produtos cruzados inesperados. Que em um banco de dados de qualquer tamanho não trivial é proibitivamente caro (e perigoso para não-selecionados!). É muito mais difícil esquecer uma relação ao usar a
join
sintaxe de estilo.fonte
Há dois aspectos diferentes a serem considerados: Desempenho e Manutenção / Legibilidade .
Manutenção / Legibilidade
Eu escolhi uma consulta diferente, pois acho que é um exemplo melhor / pior do que a consulta original que você postou.
O que parece melhor para você e é mais legível?
Ou...
Para mim, pessoalmente, o primeiro é bastante legível. Você vê que estamos juntando tabelas com
INNER JOIN
, o que significa que estamos puxando as linhas correspondentes na cláusula de junção subseqüente (por exemplo, "junte Employee com EmployeeDepartmentHistory em BusinessEntityID e inclua essas linhas").O último, a vírgula não significa nada para mim. Isso me faz pensar no que você está fazendo com todos esses
WHERE
predicados de cláusulas.O primeiro lê mais como meu cérebro pensa. Eu olho para o SQL o dia inteiro todos os dias e as vírgulas para junções. O que me leva ao meu próximo ponto ...
Todos são junções. Até as vírgulas são uma junção. O fato de o autor não os chamar de fato é a queda deles ... não é óbvio. Deveria ser óbvio. Você está juntando dados relacionais, independentemente de especificar
JOIN
ou,
.atuação
Definitivamente, isso depende do RDBMS. Só posso falar em nome do Microsoft SQL Server. Em termos de desempenho, estes são equivalentes. Como você sabe? Capture os planos pós-execução e veja o que exatamente o SQL Server está fazendo por cada uma destas instruções:
Na imagem acima, destaquei que estou usando as duas consultas acima, diferindo apenas nos caracteres explícitos da junção (
JOIN
vs,
). O SQL Server faz exatamente a mesma coisa.Sumário
Não use vírgulas. Use
JOIN
instruções explícitas .fonte
Não, não é verdade. O autor está configurando seus leitores para confusão e incentivando a programação de cultos de carga que evita uma diferença estrutural muito poderosa entre a sintaxe padrão e essa variante mais antiga que ele prefere. Especificamente, uma cláusula WHERE desorganizada torna mais difícil descobrir o que torna sua consulta especial.
Seu exemplo leva um leitor a gerar um mapa mental de seu significado, que tem uma enorme quantidade de confusão.
Aproximadamente, o acima é:
Com um mapa mental como esse, o leitor (que está escrevendo o SQL manualmente por algum motivo) pode cometer um erro muito fácil, possivelmente omitindo uma ou mais tabelas. E um leitor de código escrito dessa maneira terá que trabalhar mais para descobrir exatamente o que o autor do SQL está tentando fazer. ("Mais difícil" está no nível de leitura de SQL com ou sem destaque de sintaxe, mas ainda é uma diferença maior que zero.)
Há uma razão pela qual o JOIN é comum, e é o velho clássico "separação de preocupações". Especificamente, para uma consulta SQL, há um bom motivo para separar como os dados são estruturados e como os dados são filtrados.
Se a consulta for escrita mais limpa, como
Então o leitor tem uma distinção mais clara entre os componentes do que está sendo solicitado. O filtro distintivo dessa consulta é separado de como seus componentes se relacionam entre si, e os componentes necessários de cada relação estão diretamente próximos ao local em que são necessários.
Obviamente, qualquer sistema de banco de dados moderno não deve ver uma diferença significativa entre os dois estilos. Mas se o desempenho do banco de dados fosse a única consideração, a consulta SQL também não teria espaço em branco ou capitalização.
fonte
Guy está cometendo um erro clássico. Ele está tentando ensinar um conceito abstrato com uma implementação específica. Assim que você faz isso, você entra nesse tipo de bagunça.
Deveria ter ensinado conceitos básicos de banco de dados primeiro, depois mostrado o SQL como uma maneira de descrevê-los.
Junções esquerda e direita, pode-se argumentar que não importam muito. Junção externa, bem, você pode usar a antiga
*=
e a=*
sintaxe.Agora você pode argumentar que a sintaxe é mais simples, mas apenas para consultas simples. Assim que você começar a tentar fazer uma consulta complexa com esta versão, poderá entrar em uma confusão horrível. A sintaxe "nova" não foi introduzida para que você pudesse fazer consultas complexas, mas para fazer consultas complexas de maneira legível e, portanto, sustentável.
fonte
O exemplo é equivalente à reformulação simples com JOINs internos. A diferença está apenas nas possibilidades adicionais que a sintaxe JOIN permite. Por exemplo, você pode especificar a ordem em que as colunas das duas tabelas envolvidas são processadas; veja, por exemplo, https://stackoverflow.com/a/1018825/259310 .
A sabedoria recebida é, em caso de dúvida, escrever suas consultas da maneira que as torna mais legíveis. Mas se as formulações JOIN ou WHERE são mais fáceis de ler parece ser uma questão de preferência pessoal, e é por isso que ambas as formas são tão difundidas.
fonte
WHERE
ou a cláusula naJOIN
declaração possa realmente afetar o desempenho, dependendo do Query Optimizer. Eu já vi isso acontecer mais de uma vez.Quando aprendi SQL, os formulários INNER JOIN, LEFT JOIN etc. não existiam. Como outras respostas já declararam, diferentes dialetos do SQL implementaram junções externas usando sintaxe idiossincrática. Essa portabilidade danificada do código SQL. Para trazer o idioma de volta, foi necessário mudar e LEFT JOIN etc. foi o que eles decidiram.
É verdade que, para cada INNER JOIN, uma junção de vírgula equivalente com a condição de junção na cláusula WHERE pode ser gravada. Levei um tempo para migrar do gosto da forma antiga para a preferência da nova forma. Aparentemente, o autor de Learning SQL the Hard Way ainda acha que o caminho antigo é mais fácil.
Existem diferenças? Bem, sim, existem. A primeira é que um INNER JOIN com uma cláusula ON revela a intenção do autor mais claramente do que o estilo antigo. O fato de a cláusula ON ser de fato uma condição de junção e não outro tipo de restrição é mais óbvio. Isso torna o código que usa INNER JOIN mais fácil de aprender ao ler do que o estilo antigo. Isso é importante ao manter o código de outra pessoa.
A segunda diferença é que o novo estilo facilita marginalmente para o otimizador de consultas descobrir a estratégia vencedora. Este é um efeito muito pequeno, mas é real.
A terceira diferença é que, quando você aprende usando INNER JOIN (ou simplesmente JOIN), fica mais fácil aprender LEFT JOIN, etc.
Além disso, não há diferença material.
fonte
Depende se você pensa em termos de conjuntos e lógica formal .....
Se você não usar a palavra-chave "join", a progressão será mais simples da lógica formal para o SQL.
Mas se, como 99% das pessoas, você não gostava de lógica formal em seu curso de matemática, então a palavra-chave join é muito mais fácil de aprender. O SQL costumava ser apresentado na universidade apenas como outra maneira de escrever consultas lógicas formais ....
fonte