Dans toutes les entreprises dans lesquelles j'ai travaillé, j'ai constaté que les gens écrivaient toujours leurs requêtes SQL dans la norme ANSI-89:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
plutôt que la norme ANSI-92:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
Pour une requête extrêmement simple comme celle-ci, il n'y a pas de grande différence de lisibilité, mais pour les requêtes volumineuses, je trouve que regrouper mes critères de jointure avec la liste de la table permet de voir beaucoup plus facilement où je pourrais avoir des problèmes dans ma jointure, et laissez-moi garder tout mon filtrage dans ma clause WHERE. Sans oublier que je pense que les jointures externes sont beaucoup plus intuitives que la syntaxe (+) d'Oracle.
Alors que j'essaie d'évangéliser ANSI-92 aux gens, y a-t-il des avantages concrets en termes de performances à utiliser ANSI-92 sur ANSI-89? J'essaierais par moi-même, mais les configurations Oracle que nous avons ici ne nous permettent pas d'utiliser EXPLAIN PLAN - ne voudriez pas que les gens essaient d'optimiser leur code, n'est-ce pas?
Réponses:
Selon "SQL Performance Tuning" par Peter Gulutzan et Trudy Pelzer, des six ou huit marques de SGBDR qu'ils ont testées, il n'y avait aucune différence dans l'optimisation ou les performances des jointures de style SQL-89 par rapport aux jointures de style SQL-92. On peut supposer que la plupart des moteurs SGBDR transforment la syntaxe en une représentation interne avant d'optimiser ou d'exécuter la requête, de sorte que la syntaxe lisible par l'homme ne fait aucune différence.
J'essaye également d'évangéliser la syntaxe SQL-92. Seize ans après son approbation, il est grand temps que les gens commencent à l'utiliser! Et toutes les marques de base de données SQL la prennent désormais en charge, il n'y a donc aucune raison de continuer à utiliser la
(+)
syntaxe Oracle non standard ou la syntaxe*=
Microsoft / Sybase.Quant à savoir pourquoi il est si difficile de briser la communauté de développeurs de l'habitude SQL-89, je ne peux que supposer qu'il existe une grande "base de la pyramide" de programmeurs qui codent par copier-coller, en utilisant des exemples anciens de livres, d'articles de magazines, ou une autre base de code, et ces personnes n'apprennent pas la nouvelle syntaxe de manière abstraite. Certaines personnes correspondent à des modèles et d'autres apprennent par cœur.
Cependant, je vois progressivement des gens utiliser la syntaxe SQL-92 plus fréquemment qu'auparavant. Je réponds aux questions SQL en ligne depuis 1994.
la source
Eh bien, la norme ANSI092 inclut une syntaxe assez odieuse. Les jointures naturelles sont une et la clause USING en est une autre. À mon humble avis, l'ajout d'une colonne à une table ne devrait pas casser le code, mais un NATURAL JOIN se brise de la manière la plus flagrante. La "meilleure" façon de casser est par erreur de compilation. Par exemple, si vous SELECT * quelque part, l'ajout d'une colonne pourraitne parvient pas à compiler. La prochaine meilleure façon d'échouer serait une erreur d'exécution. C'est pire parce que vos utilisateurs peuvent le voir, mais cela vous avertit toujours que vous avez cassé quelque chose. Si vous utilisez ANSI92 et écrivez des requêtes avec des jointures NATURELLES, il ne se cassera pas au moment de la compilation et ne se cassera pas au moment de l'exécution, la requête commencera soudainement à produire des résultats erronés. Ces types de bugs sont insidieux. Les rapports tournent mal, la divulgation potentiellement financière est incorrecte.
Pour ceux qui ne connaissent pas NATURAL Joins. Ils joignent deux tables sur chaque nom de colonne qui existe dans les deux tables. Ce qui est vraiment cool lorsque vous avez une clé à 4 colonnes et que vous en avez assez de la taper. Le problème survient lorsque Table1 a une colonne préexistante nommée DESCRIPTION et que vous ajoutez une nouvelle colonne à Table2 nommée, oh je ne sais pas, quelque chose d'innocent comme, mmm, DESCRIPTION et maintenant vous joignez les deux tables sur un VARCHAR2 (1000) champ de forme libre.
La clause USING peut conduire à une ambiguïté totale en plus du problème décrit ci-dessus. Dans un autre article SO , quelqu'un a montré ce SQL ANSI-92 et a demandé de l'aide pour le lire.
C'est complètement ambigu. J'ai mis une colonne UserID dans les tables des entreprises et des utilisateurs et il n'y a pas de plainte. Que faire si la colonne UserID dans les entreprises est l'ID de la dernière personne à modifier cette ligne?
Je suis sérieux, quelqu'un peut-il expliquer pourquoi une telle ambiguïté était nécessaire? Pourquoi est-il intégré directement dans la norme?
Je pense que Bill a raison de dire qu'il existe une grande base de développeurs qui copient / collent là-bas à travers le codage. En fait, je peux admettre que je suis un peu un quand il s'agit d'ANSI-92. Chaque exemple que j'ai vu montre que plusieurs jointures sont imbriquées entre parenthèses. Honnêteté, cela rend au mieux le choix des tables dans le sql difficile. Mais un évangiliste SQL92 a expliqué que cela forcerait en fait un ordre de jointure. JESUS ... tous ces Copy-pasters que j'ai vus sont en train de forcer un ordre de jointure - un travail qui est 95% du temps mieux laissé aux optimiseurs, en particulier un copier / coller.
Tomalak a bien compris quand il a dit:
Cela doit me donner quelque chose et je ne vois pas d'avantage. Et s'il y a un avantage, les négatifs sont un albatros trop gros pour être ignoré.
la source
SELECT *
(puis découvrir que le client dépend de l'ordre des champs) - Il se sent juste un peu bâcléQuelques raisons me viennent à l'esprit:
Pour ma part, je fais toutes mes jointures dans la syntaxe SQL-92, et je convertis du code là où je peux. C'est le moyen le plus propre, le plus lisible et le plus puissant de le faire. Mais il est difficile de convaincre quelqu'un d'utiliser le nouveau style, quand il pense que cela lui fait mal en termes de travail de frappe sans changer le résultat de la requête.
la source
En réponse au message NATURAL JOIN et USING ci-dessus.
POURQUOI verriez-vous le besoin de les utiliser - ils n'étaient pas disponibles dans ANSI-89 et ont été ajoutés pour ANSI-92 comme ce que je ne peux voir que comme un raccourci.
Je ne laisserais jamais une jointure au hasard et je spécifierais toujours la table / l'alias et l'identifiant.
Pour moi, la seule façon de procéder est ANSI-92. Il est plus verbeux et la syntaxe n'est pas appréciée par les adeptes d'ANSI-89, mais elle sépare parfaitement vos JOINS de votre FILTRAGE.
la source
Tout d'abord, permettez-moi de dire que dans SQL Server, la syntaxe de jointure externe (* =) ne donne pas toujours des résultats corrects. Il y a des moments où il interprète cela comme une jointure croisée et non comme une jointure externe. Il y a donc une bonne raison d'arrêter de l'utiliser. Et cette syntaxe de jointure externe est une fonctionnalité obsolète et ne sera pas dans la prochaine version de SQL Server après SQL Server 2008. Vous pourrez toujours effectuer les jointures internes, mais pourquoi diable quelqu'un voudrait-il le faire? Ils ne sont pas clairs et beaucoup plus difficiles à maintenir. Vous ne savez pas facilement ce qui fait partie de la jointure et ce qui n'est en réalité que la clause where.
Une des raisons pour lesquelles je pense que vous ne devriez pas utiliser l'ancienne syntaxe est que la compréhension des jointures et de ce qu'elles font et ne font pas est une étape critique pour quiconque écrira du code SQL. Vous ne devez pas écrire de code SQL sans bien comprendre les jointures. Si vous les comprenez bien, vous arriverez probablement à la conclusion que la syntaxe ANSI-92 est plus claire et plus facile à maintenir. Je n'ai jamais rencontré un expert SQL qui n'utilisait pas la syntaxe ANSI-92 de préférence à l'ancienne syntaxe.
La plupart des personnes que j'ai rencontrées ou avec lesquelles j'ai eu affaire et qui utilisent l'ancien code ne comprennent vraiment pas les jointures et ont donc des problèmes lors de l'interrogation de la base de données. C'est mon expérience personnelle donc je ne dis pas que c'est toujours vrai. Mais en tant que spécialiste des données, j'ai dû trop réparer ces déchets au fil des ans pour ne pas y croire.
la source
J'ai appris l'ANSI-89 à l'école et j'ai travaillé dans l'industrie pendant quelques années. Puis j'ai quitté le monde fabuleux des SGBD pendant 8 ans. Mais ensuite je suis revenu et ce nouveau truc ANSI 92 était enseigné. J'ai appris la syntaxe Join On et maintenant j'enseigne le SQL et je recommande la nouvelle syntaxe JOIN ON.
Mais l'inconvénient que je vois est que les sous-requêtes corrélées ne semblent pas avoir de sens à la lumière des jointures ANSI 92. Lorsque les informations de jointure ont été incluses dans le WHERE et que les sous-requêtes corrélées sont «jointes» dans le WHERE, tout semblait correct et cohérent. Dans ANSI 92, les critères de jointure de table ne sont pas dans le WHERE et la sous-requête "jointure" est, la syntaxe semble incohérente. D'un autre côté, essayer de «corriger» cette incohérence ne ferait probablement qu'empirer les choses.
la source
Je ne connais pas la réponse avec certitude ... c'est une guerre religieuse (albiet d'un degré moindre que Mac-Pc ou autres)
On suppose que jusqu'à récemment, Oracle (et peut-être d'autres fournisseurs également) n'a pas adopté la norme ANSI-92 (je pense que c'était dans Oracle v9, ou à peu près) et donc, pour les développeurs DBA / Db travaillant dans des entreprises qui utilisaient toujours ces versions, (ou voulaient que le code soit portable sur les serveurs susceptibles d'utiliser ces versions, ils devaient s'en tenir à l'ancienne norme ...
C'est vraiment dommage, car la nouvelle syntaxe de jointure est beaucoup plus lisible, et l'ancienne syntaxe génère des résultats erronés (incorrects) dans plusieurs scénarios bien documentés.
la source
INNER JOIN
en 1995, maisLEFT JOIN
pas avant 1996. MySQL l'a pris en charge au moins depuis 3.23, sorti en 1999; PostgreSQL au moins depuis la version 7.2, sortie en 2002. Certains googlages occasionnels ne me donnent aucune réponse pour Teradata.Inertie et praticité.
ANSI-92 SQL est comme la saisie tactile. D'une certaine manière théorique, cela pourrait tout améliorer un jour, mais je peux taper beaucoup plus rapidement en regardant les touches avec quatre doigts maintenant. J'aurais besoin de revenir en arrière pour aller de l'avant, sans aucune garantie qu'il y aurait jamais une récompense.
L'écriture SQL représente environ 10% de mon travail. Si j'ai besoin de ANSI-92 SQL pour résoudre un problème que ANSI-89 SQL ne peut pas résoudre, je vais l'utiliser. (Je l'utilise dans Access, en fait.) Si l'utiliser tout le temps m'aiderait à résoudre mes problèmes existants beaucoup plus rapidement, je passerais le temps à l'assimiler. Mais je peux sortir ANSI-89 SQL sans jamais penser à la syntaxe. Je suis payé pour résoudre des problèmes - penser à la syntaxe SQL est une perte de temps et d'argent de mon employeur.
Un jour, jeune Grasshopper, vous défendrez votre utilisation de la syntaxe SQL ANSI-92 contre des jeunes qui se plaignent que vous devriez utiliser SQL3 (ou autre). Et alors vous comprendrez. :-)
la source
J'avais une requête qui avait été écrite à l'origine pour SQL Server 6.5, qui ne prenait pas en charge la syntaxe de jointure SQL 92, c'est-à-dire
était plutôt écrit comme
La requête existait depuis un certain temps et les données pertinentes s'étaient accumulées pour que la requête s'exécute trop lentement, environ 90 secondes pour se terminer. Au moment où ce problème est survenu, nous étions passés à SQL Server 7.
Après avoir manqué avec les index et autres œufs de Pâques, j'ai changé la syntaxe de jointure pour qu'elle soit conforme à SQL 92. Le temps de requête est tombé à 3 secondes.
Il y a une bonne raison de changer.
Republié d' ici .
la source
Je peux répondre du point de vue d'un développeur moyen, connaissant juste assez de SQL pour comprendre les deux syntaxes, mais toujours googler la syntaxe exacte de l'insertion à chaque fois que j'en ai besoin ... :-P (je ne fais pas de SQL toute la journée , juste en réglant quelques problèmes de temps en temps.)
Eh bien, en fait, je trouve la première forme plus intuitive, ne faisant aucune hiérarchie apparente entre les deux tables. Le fait d'avoir appris SQL avec peut-être de vieux livres, montrant la première forme, n'aide probablement pas ... ;-)
Et la première référence que je trouve sur un sql select recherche dans Google (qui renvoie principalement des réponses en français pour moi ... ) montre d'abord l'ancienne forme (puis expliquez la seconde).
Juste en donnant quelques indices sur la question "pourquoi" ... ^ _ ^ Je devrais lire un bon livre moderne (indépendant de la base de données) sur le sujet. Si quelqu'un a des suggestions ...
la source
Je ne peux pas parler pour toutes les écoles, mais à mon université, lorsque nous faisions le module SQL de notre cours, ils n'enseignaient pas ANSI-92, ils enseignaient ANSI-89 - sur un vieux système VAX en plus! Je n'ai pas été exposé à ANSI-92 jusqu'à ce que je commence à fouiller dans Access après avoir créé des requêtes à l'aide du concepteur de requêtes, puis à creuser dans le code SQL. Réalisant que je n'avais aucune idée de la façon dont cela complétait les jointures, ou des implications de la syntaxe, j'ai commencé à creuser plus profondément pour pouvoir le comprendre.
Étant donné que la documentation disponible n'est pas exactement intuitive dans de nombreux cas, et que les gens ont tendance à s'en tenir à ce qu'ils savent et, dans de nombreux cas, ne s'efforcent pas d'apprendre plus que ce dont ils ont besoin pour faire leur travail, c'est facile de voir pourquoi l'adoption prend si longtemps.
Bien sûr, il y a ces évangélistes techniques qui aiment bricoler et comprendre et ce sont généralement ces types qui adoptent les principes «plus récents» et essaient de convertir le reste.
Curieusement, il me semble que beaucoup de programmeurs sortent de l'école et arrêtent d'avancer; pensant que parce que c'est ce qu'on leur a appris, c'est comme ça que ça se fait. Ce n'est que lorsque vous enlevez vos œillères que vous réalisez que l'école était uniquement destinée à vous enseigner les bases et à vous donner suffisamment de compréhension pour apprendre le reste vous-même et qu'en réalité vous avez à peine effleuré la surface de ce qu'il y a à savoir; maintenant c'est votre travail de continuer sur cette voie.
Bien sûr, ce n'est que mon opinion basée sur mon expérience.
la source
1) Méthode standard pour écrire OUTER JOIN, par rapport à * = ou (+) =
2) JOINT NATUREL
3) Dépendre du moteur de base de données, les tendances ANSI-92 pour être plus optimale.
4) Optimisation manuelle:
Disons que nous avons la syntaxe suivante (ANSI-89):
Cela pourrait être écrit comme suit:
Mais aussi comme:
Tous (1), (2), (3) renvoient le même résultat, mais ils sont optimisés différemment, cela dépend du moteur de base de données mais la plupart le font:
5) Les requêtes plus longues sont moins compliquées.
la source
Les raisons pour lesquelles les gens utilisent ANSI-89 à partir de mon expérience pratique avec des programmeurs et des stagiaires anciens et jeunes et de nouveaux diplômés:
Personnellement, je préfère ANSI-92 et modifie chaque requête que je vois dans la syntaxe ANSI-89 parfois uniquement pour mieux comprendre l'instruction SQL à portée de main. Mais j'ai réalisé que la majorité des personnes avec lesquelles je travaille ne sont pas assez qualifiées pour écrire des jointures sur de nombreuses tables. Ils codent aussi bien qu'ils le peuvent et utilisent ce qu'ils ont mémorisé la première fois qu'ils ont rencontré une instruction SQL.
la source
Voici quelques points comparant SQL-89 et SQL-92 et clarifiant certaines idées fausses dans d'autres réponses.
NATURAL JOINS
sont une idée horrible. Ils sont implicites et nécessitent des méta-informations sur la table. Rien dans SQL-92 ne nécessite leur utilisation, alors ignorez-les simplement . Ils ne sont pas pertinents pour cette discussion.USING
est une excellente idée, elle a deux effets:id
sur les deux tables. Une fois que vous avez joint les tables, cela devient ambigu et nécessite un alias explicite. De plus, lesid
s sur la jointure avaient presque certainement des données différentes. Si vous joignez personne à entreprise, vous devez maintenant créer un alias unid
àperson_id
et unid
àcompany_id
, sans quoi la jointure produirait deux colonnes ambiguës. L'utilisation d'un identifiant unique au monde pour la clé de substitution de la table est la convention avec laquelle les récompenses standard sont utiliséesUSING
.CROSS JOIN
. ACROSS JOIN
ne réduit pas l'ensemble, il l'agrandit implicitement.FROM T1,T2
est le même queFROM T1 CROSS JOIN T2
, qui produit une jointure cartésienne qui n'est généralement pas ce que vous voulez. Avoir la sélectivité pour réduire cela à unWHERE
conditionnel éloigné signifie que vous êtes plus susceptible de faire des erreurs lors de la conception.,
explicites SQL-89 et SQL-92JOIN
ont une priorité différente.JOIN
a une priorité plus élevée. Pire encore, certaines bases de données comme MySQL se sont trompées pendant très longtemps. . Donc, mélanger les deux styles est une mauvaise idée, et le style beaucoup plus populaire aujourd'hui est le style SQL-92.la source
Oracle n'implémente pas du tout bien ANSI-92. J'ai eu plusieurs problèmes, notamment parce que les tables de données d'Oracle Apps sont très bien dotées de colonnes. Si le nombre de colonnes dans vos jointures dépasse environ 1050 colonnes (ce qui est très facile à faire dans les applications), vous obtiendrez cette fausse erreur qui n'a absolument aucun sens logique:
La réécriture de la requête pour utiliser la syntaxe de jointure à l'ancienne fait disparaître le problème, ce qui semble pointer du doigt la faute sur l'implémentation des jointures ANSI-92.
Jusqu'à ce que je rencontre ce problème, j'étais un fervent promoteur de l'ASNI-92, en raison des avantages de réduire le risque de jointure croisée accidentelle, ce qui est beaucoup trop facile à faire avec la syntaxe à l'ancienne.
Maintenant, cependant, je trouve beaucoup plus difficile d'insister là-dessus. Ils soulignent la mauvaise implémentation d'Oracle et disent: «Nous le ferons à notre façon, merci».
la source
Un nouveau standard SQL hérite de tout du standard précédent, alias «les chaînes de la compatibilité». Ainsi, le style de jointure «ancien» / «séparé par des virgules» / «non qualifié» est une syntaxe SQL-92 parfaitement valide.
Maintenant, je soutiens que SQL-92
NATURAL JOIN
est la seule jointure dont vous avez besoin. Par exemple, je soutiens qu'il est supérieurinner join
parce qu'il ne génère pas de colonnes en double - plus de variables de plage dansSELECT
clauses pour lever l'ambiguïté des colonnes! Mais je ne peux pas m'attendre à changer tous les cœurs et tous les esprits, je dois donc travailler avec des codeurs qui continueront à adopter ce que je considère personnellement comme des styles de jointure hérités (et ils peuvent même se référer aux variables de plage comme des `` alias ''!). C'est la nature du travail d'équipe et de ne pas fonctionner dans le vide.L'une des critiques du langage SQL est que le même résultat peut être obtenu en utilisant un certain nombre de syntaxes sémantiquement équivalentes (certaines utilisant l'algèbre relationnelle, d'autres utilisant le calcul relationnel), où le choix du `` meilleur '' revient simplement à un style personnel . Je suis donc aussi à l'aise avec les jointures «à l'ancienne» que je le suis avec
INNER
. Que je prenne le temps de les réécrire enNATURAL
fonction du contexte.la source