Dans Learn SQL the Hard Way (exercice 6) , l'auteur présente la requête suivante:
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";
et continue ensuite en disant que:
Il existe en fait d'autres moyens pour faire fonctionner ce type de requête, appelé "jointure". J'évite ces concepts pour l'instant car ils sont incroyablement déroutants. Tenez-vous-en à cette façon de joindre les tables pour le moment et ignorez les personnes qui essaient de vous dire que cela est en quelque sorte plus lent ou "de classe inférieure".
Est-ce vrai? Pourquoi ou pourquoi pas?
Réponses:
Avec l’approche de l’auteur, l’enseignement des OUTER JOINs devient beaucoup plus difficile. La clause ON dans INNER JOIN ne m'a jamais déconcerté comme beaucoup d'autres choses. Peut-être que c'est parce que je n'ai jamais appris à l'ancienne. J'aimerais penser qu'il y a une raison pour laquelle nous nous en sommes débarrassés et que ce n'était pas pour être méchant et appeler cette méthode classe inférieure.
C'est vrai dans le scénario très étroit que l'auteur a créé:
Dans le cadre d’une progression d’enseignement, je pense qu’il est plus facile de la décomposer et d’avoir une progression naturelle:
Les concepts de jonction et de filtrage des tables ne sont pas vraiment les mêmes. L' apprentissage de la syntaxe correcte va maintenant avoir plus de report quand vous apprenez REJOINT à moins que l'OUTER auteur a l' intention d'enseigner des choses obsolètes / désapprouvées comme:
*= or =*
.la source
*=
ou=*
indiquait des jointures externes gauches ou droites, un autre que j’utilisais ne supportait que les jointures externes gauches à l’aide d’un|=
opérateur.+=
ou peut-être était-il=+
. Je crois que*=
c'était Transact-SQL (Sybase et plus tard MS-SQL). Toujours, bon point.WHERE
clause. (J'ai entendu parler de cela comme une adhésion thêta , mais je ne suis pas sûr que ce soit correct.)Que cela soit plus lent dépend de l'optimiseur de requête et de la façon dont il rationalise la requête (ce que vous écrivez n'est pas ce qui est exécuté). Cependant, le gros problème de cette citation est qu’elle ignore complètement le fait qu’il existe différents types de jointures qui fonctionnent de manière totalement différente. Par exemple, ce qui est dit est (théoriquement) vrai pour
inner joins
, mais ce n'est pas vrai pourouter joins
(left joins
etright joins
).la source
INNER JOIN
ouLEFT OUTER JOIN
. Ils ne sont pas "incroyablement déroutants". SQL peut devenir incroyablement déroutant, mais ce n’est pas un exemple.L'auteur présente un cas simple d'utilisation de l'ancienne ou de la nouvelle syntaxe. Je ne suis pas d'accord sur son affirmation selon laquelle les jointures sont source de confusion insensée, car la jonction de tables est un concept fondamental de requête SQL. Donc, l’auteur aurait peut-être dû passer un peu de temps à expliquer le fonctionnement de JOINS avant de prononcer une déclaration avec opinion, ainsi qu’à faire un exemple de requête à plusieurs tables.
Il faut utiliser la syntaxe la plus récente. L'argument principal est que votre requête aura:
À l'aide de l'ancien style, les critères de jointure et de filtrage sont combinés, ce qui peut conduire à la confusion dans des cas plus complexes.
En outre, on peut obtenir un produit cartésien en oubliant un critère de jointure dans la clause de filtre:
en utilisant l'ancienne syntaxe.
L'utilisation de la nouvelle syntaxe spécifie également comment la jointure doit se produire, ce qui est important pour savoir si vous voulez un INNER, un LEFT OUTER, etc., de sorte qu'il est plus explicite en ce qui concerne la syntaxe JOIN qui améliore la lisibilité pour ceux qui ne connaissent pas les tables de jointure.
la source
Cela ne devrait pas être le cas, l'analyseur de requête devrait générer une représentation interne équivalente pour les requêtes équivalentes, quelle que soit leur écriture. L'auteur n'utilise que la syntaxe pré-SQL-92, raison pour laquelle il mentionne qu'elle pourrait être considérée comme "à l'ancienne" ou "basse classe". En interne, l'analyseur et l'optimiseur doivent générer le même plan de requête.
la source
J'ai appris SQL de cette façon, y compris le
*=
syntaxe des jointures externes. Pour moi, c'était très intuitif puisque toutes les relations ont la même priorité et permettent de mieux configurer les requêtes en une série de questions: que voulez-vous? D'où les voulez-vous? Lesquel tu veux?En faisant de la
join
syntaxe, cela perturbe plus fortement le processus de pensée envers les relations. Et personnellement, je trouve le code beaucoup moins lisible avec les tables et les relations mélangées.Au moins dans MSSQL, il n'y a aucune différence significative dans les performances des requêtes, en supposant que vous utilisiez le même ordre de jointure. Cela dit, l’ apprentissage (et l’utilisation) de SQL de cette manière pose un énorme problème. Si vous oubliez une de vos relations, vous obtiendrez des produits croisés inattendus. Qui sur une base de données de toute taille non-triviale est prohibitif (et dangereux pour les non-sélectionnés!). Il est beaucoup plus difficile d'oublier une relation lorsque vous utilisez la
join
syntaxe de style.la source
Il convient de prendre en compte deux aspects différents: performances et maintenabilité / lisibilité .
Maintenabilité / lisibilité
J'ai choisi une requête différente, car je pense que c'est un exemple meilleur / pire que la requête d'origine que vous avez postée.
Qu'est-ce qui vous va le mieux et qui est plus lisible?
Ou...
Pour moi personnellement, le premier est assez lisible. Vous voyez que nous joignons des tables avec
INNER JOIN
, ce qui signifie que nous extrayons les lignes qui correspondent à la clause de jointure suivante (c'est-à-dire "rejoindre un employé avec EmployeeDepartmentHistory sur BusinessEntityID et inclure ces lignes").Ce dernier, la virgule ne signifie rien pour moi. Je me demande ce que vous faites avec tous ces
WHERE
prédicats d’article.Le premier lit plus comme mon cerveau pense. Je regarde SQL toute la journée, tous les jours, ainsi que les virgules pour les jointures. Ce qui m'amène à mon prochain point ...
Ils sont tous joints. Même les virgules sont une jointure. Le fait que l'auteur ne les appelle pas, c'est bien leur perte ... ce n'est pas évident. Cela devrait être évident. Vous joignez des données relationnelles, que vous spécifiiez
JOIN
ou,
.Performance
Cela dépendra très certainement du SGBDR. Je ne peux parler qu'au nom de Microsoft SQL Server. Les performances sont équivalentes. Comment le sais-tu? Capturez les plans de post-exécution et voyez ce que SQL Server fait exactement pour chacune de ces instructions:
Dans l'image ci-dessus, j'ai souligné que j'utilise les deux requêtes comme ci-dessus, ne différant que par les caractères explicites de la jointure (
JOIN
vs,
). SQL Server fait exactement la même chose.Sommaire
N'utilisez pas de virgules. Utilisez des
JOIN
déclarations explicites .la source
Non, ce n'est pas vrai du tout. L’auteur prépare ses lecteurs à la confusion et encourage une programmation culte du fret qui évite une différence structurelle très forte entre la syntaxe standard et cette variante plus ancienne qu’il préfère. Plus précisément, une clause WHERE encombrée rend plus difficile la compréhension de ce qui rend sa requête si spéciale.
Son exemple conduit un lecteur à générer une carte mentale de sa signification qui a beaucoup d'encombrement.
En gros, ce qui précède est:
Avec une telle carte mentale, le lecteur (qui écrit le code SQL à la main pour une raison quelconque) peut très facilement commettre une erreur, éventuellement en omettant un ou plusieurs tableaux. Et un lecteur de code écrit de cette manière devra travailler plus fort pour comprendre exactement ce que l'auteur de SQL essaie de faire. ("Harder" est au niveau de la lecture SQL avec ou sans mise en surbrillance de la syntaxe, mais la différence est toujours supérieure à zéro.)
Il y a une raison pour laquelle les JOIN sont communs, et c'est le vieux classique "séparation des préoccupations" canard. En particulier, pour une requête SQL, il existe une bonne raison de séparer la structure des données et leur filtrage.
Si la requête est écrite plus propre, telle que
Ensuite, le lecteur a une distinction plus claire entre les composants de ce qui est demandé. Le filtre distinctif de cette requête est séparé de la façon dont ses composants sont en relation et les composants nécessaires de chaque relation sont directement à côté de l'endroit où ils sont requis.
Bien entendu, aucun système de base de données moderne ne devrait voir une différence significative entre les deux styles. Mais si les performances de la base de données étaient la seule considération, la requête SQL n'aurait pas non plus d'espace blanc ou de majuscule.
la source
Guy fait une erreur classique. Il essaie d'enseigner un concept abstrait avec une implémentation spécifique. Dès que vous faites cela, vous vous retrouvez dans ce genre de désordre.
Devrait avoir d'abord enseigné les concepts de base de base de données, puis montré SQL comme une façon de les décrire.
Les jointures gauche et droite pourraient être discutées, elles importent peu. Jointure externe, vous pouvez utiliser l’ancienne
*=
et la=*
syntaxe.Vous pouvez maintenant dire que la syntaxe est plus simple, mais uniquement pour les requêtes simples. Dès que vous commencez à essayer de faire une requête complexe avec cette version, vous pouvez vous retrouver dans un fouillis horrible. La "nouvelle" syntaxe n'a pas été introduite pour vous permettre de faire des requêtes complexes, mais plutôt pour que vous fassiez des requêtes complexes de manière lisible et donc maintenable.
la source
L'exemple équivaut à la reformulation simple avec JOIN internes. La différence réside uniquement dans les possibilités supplémentaires offertes par la syntaxe JOIN. Par exemple, vous pouvez spécifier l'ordre dans lequel les colonnes des deux tables impliquées sont traitées; voir par exemple https://stackoverflow.com/a/1018825/259310 .
La sagesse reçue consiste, en cas de doute, à écrire vos questions de manière à les rendre plus lisibles. Mais, que les formules JOIN ou WHERE soient plus faciles à lire, cela semble être une question de préférence personnelle, ce qui explique pourquoi les deux formes sont si répandues.
la source
WHERE
utilisiez la clause ou que vous mettiez la clause dans l’JOIN
instruction puisse réellement avoir un impact sur les performances en fonction de l’optimiseur de requêtes. Je l'ai vu arriver plus d'une fois.Quand j'ai appris le SQL, les formulaires INNER JOIN, LEFT JOIN, etc. n'existaient pas. Comme d'autres réponses l'ont déjà indiqué, différents dialectes de SQL ont chacun implémenté des jointures externes utilisant une syntaxe idiosyncratique. Cette portabilité endommagée du code SQL. Rassembler la langue a nécessité quelques changements, et LEFT JOIN, etc., a été choisi.
Il est vrai que pour chaque INNER JOIN, une jointure équivalente avec la condition de jointure de la clause WHERE peut être écrite. Il m'a fallu un certain temps pour migrer d'aimer l'ancien formulaire à préférer le nouveau formulaire. Apparemment, l'auteur de Learning SQL the Hard Way pense toujours que l'ancienne méthode est plus facile.
Y a-t-il des différences? Oui, il y en a. La première est qu'un INNER JOIN avec une clause ON révèle l'intention de l'auteur plus clairement que l'ancien style. Le fait que la clause ON soit en fait une condition de jointure et non un autre type de restriction est plus évident. Cela rend le code utilisant INNER JOIN plus facile à apprendre lors de la lecture que l'ancien style. Ceci est important lors de la maintenance du code de quelqu'un d'autre.
La seconde différence est que le nouveau style permet à l'optimiseur de requêtes de découvrir plus facilement la stratégie gagnante. C'est un très petit effet, mais c'est réel.
La troisième différence est que lorsque vous apprenez à utiliser INNER JOIN (ou simplement plain JOIN), cela facilite l'apprentissage de LEFT JOIN, etc.
En dehors de cela, il n'y a aucune différence matérielle.
la source
Cela dépend si vous pensez en termes d’ensembles et de logique formelle .....
Si vous n'utilisez pas le mot-clé "join", la progression de la logique formelle vers SQL est simplifiée.
Mais si, comme 99% des personnes, vous n'aimiez pas la logique formelle dans votre diplôme en mathématiques, le mot clé join est un outil plus facile à apprendre. Auparavant, le code SQL était présenté à l’université comme un autre moyen d’écrire des requêtes de logique formelles ....
la source