109 votes

Pourquoi la norme SQL ANSI-92 n'est-elle pas mieux adoptée que ANSI-89?

À chaque entreprise où j'ai travaillé, j'ai constaté que les gens continuent d'écrire leurs requêtes SQL en utilisant la norme ANSI-89 :

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

au lieu de 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 une grande différence en termes de lisibilité, mais pour des requêtes plus complexes, je trouve que regrouper mes critères de jointure avec l'énumération des tables rend beaucoup plus facile de repérer d'éventuels problèmes de jointure, et me permet de garder tous mes filtres dans ma clause WHERE. Sans oublier que je pense que les jointures externes sont beaucoup plus intuitives que la syntaxe (+) dans Oracle.

Alors que j'essaie de promouvoir la norme ANSI-92 auprès des gens, y a-t-il des avantages de performance concrets à utiliser ANSI-92 plutôt que ANSI-89 ? Je pourrais essayer par moi-même, mais les configurations Oracle que nous avons ici ne nous permettent pas d'utiliser EXPLAIN PLAN - on ne voudrait pas que les gens tentent d'optimiser leur code, n'est-ce pas ?

7 votes

Un avantage principal de la notation JOIN SQL-92 est qu'il existe une manière standard et relativement saine d'écrire LEFT OUTER JOIN et ses variantes. Chaque SGBD avait sa propre syntaxe de variante (généralement mauvaise ; en fait, je pense, sans exception, les notations étaient mauvaises) et souvent avec des sémantiques légèrement différentes. SQL-92 a corrigé cela, et la nouvelle notation vaut la peine d'être utilisée sur ces seuls motifs. Je pense que c'est plus clair de toute façon, une fois que vous y êtes habitué. Cela prend un peu de temps pour s'y habituer, mais ce n'est pas difficile, et une fois converti, il n'y a pas de retour en arrière.

0 votes

Sémantique, sémantique, anti-sémantique!

0 votes

Je suis un peu en retard pour la fête ici, mais personne n'a semblé avoir souligné qu'Oracle lui-même recommande d'utiliser la syntaxe OUTER JOIN de la clause FROM plutôt que l'opérateur de jointure Oracle

79voto

Bill Karwin Points 204877

Selon "SQL Performance Tuning" de Peter Gulutzan et Trudy Pelzer, parmi les six ou huit marques de SGBDR testées, il n'y avait aucune différence d'optimisation ou de performance entre les jointures de style SQL-89 et SQL-92. On peut supposer que la plupart des moteurs de SGBDR transforment la syntaxe en une représentation interne avant d'optimiser ou d'exécuter la requête, donc la syntaxe lisible par l'humain ne fait aucune différence.

J'essaie également de promouvoir 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 bases de données SQL le supportent maintenant, donc il n'y a aucune raison de continuer à utiliser la syntaxe non standard (+) d'Oracle ou *= de Microsoft/Sybase.

Quant à savoir pourquoi il est si difficile de faire abandonner à la communauté des développeurs la habitude du SQL-89, je ne peux que supposer qu'il y a une grande "base de la pyramide" de programmeurs qui codent par copier-coller, en utilisant d'anciens exemples de livres, d'articles de magazines ou d'un autre base de code, et ces personnes n'apprennent pas de nouvelle syntaxe de manière abstraite. Certains font correspondre des modèles, et d'autres apprennent par cœur.

Je vois progressivement des personnes utiliser la syntaxe SQL-92 plus fréquemment qu'auparavant, cependant. Je réponds à des questions SQL en ligne depuis 1994.

6 votes

Je suis tout à fait d'accord. Je travaille avec de nombreux codeurs SQL qui ont appris leur SQL il y a 15 ans ou plus (comme moi-même) et qui ne connaissent rien de toute innovation depuis leurs débuts. Ils n'ont également aucun intérêt à s'informer.

8 votes

D'accord, mais ajoutez qu'il existe des scénarios bien documentés où l'ancienne syntaxe de jointure ANSI-89 produit des résultats incorrects... notamment les jointures externes lorsqu'il y a des prédicats de filtrage conditionnels sur des colonnes non liées par la jointure du côté "externe".

0 votes

J'ai remarqué d'énormes gains de performance en utilisant le code ANSI-92 plutôt que le code ANSI-89 sur MSSQL (2k et 2k5) ici au travail. Je pense que MSSQL est en fait assez stupide pour faire une jointure cartésienne, puis filtrer les résultats avec la clause where... ou peut-être qu'il empêche simplement l'utilisation de l'index ?

17voto

Eh bien, la norme ANSI092 comprend une syntaxe assez atroce. Les jointures naturelles en font partie, tout comme la clause USING. À mon avis, l'ajout d'une colonne à une table ne devrait pas casser le code, mais une jointure naturelle le fait de la manière la plus flagrante. La "meilleure" façon de casser est par une erreur de compilation. Par exemple, si vous faites SELECT * quelque part, l'ajout d'une colonne pourrait échouer à la compilation. La deuxième meilleure façon d'échouer serait une erreur d'exécution. C'est pire car vos utilisateurs pourraient le voir, mais cela vous donne quand même un avertissement que vous avez cassé quelque chose. Si vous utilisez ANSI92 et écrivez des requêtes avec des jointures naturelles, cela ne cassera pas lors de la compilation et ne cassera pas lors de l'exécution, la requête commencera simplement à produire soudainement de mauvais résultats. Ces types de bugs sont insidieux. Les rapports se faussent, les divulgations financières potentielles sont incorrectes.

Pour ceux qui ne connaissent pas les jointures naturelles. Elles joignent deux tables sur chaque nom de colonne qui existe dans les deux tables. C'est vraiment cool lorsque vous avez une clé à 4 colonnes et que vous en avez marre de la taper. Le problème survient lorsque la 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'anodin comme, mmm, DESCRIPTION et maintenant vous joignez les deux tables sur un champ VARCHAR2(1000) qui est libre.

La clause USING peut conduire à une ambiguïté totale en plus du problème décrit ci-dessus. Dans un autre message SO, quelqu'un a montré ce SQL ANSI-92 et a demandé de l'aide pour le lire.

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

C'est complètement ambigu. J'ai mis une colonne UserID dans les tables Companies et users et il n'y a aucune plainte. Et si la colonne UserID dans les companies est l'ID de la dernière personne à avoir modifié cette ligne ?

Je suis sérieux, quelqu'un peut-il expliquer pourquoi une telle ambiguïté était nécessaire ? Pourquoi est-elle intégrée directement dans la norme ?

Je pense que Bill a raison, il y a une grande base de développeurs qui copient/collent leur code de cette façon. En fait, je peux admettre que je suis un peu comme ça quand il s'agit de ANSI-92. Chaque exemple que j'ai vu montrait plusieurs jointures imbriquées entre parenthèses. Honnêtement, cela rend le repérage des tables dans la requête SQL difficile au mieux. Mais ensuite, un évangéliste de SQL92 a expliqué que cela forcerait en fait un ordre de jointure. MON DIEU... tous ces copieurs-collateurs que j'ai vus forcent maintenant réellement un ordre de jointure - une tâche qui est 95% du temps mieux laissée aux optimiseurs, surtout un copieur-collateur.

Tomalak a raison quand il a dit,

les gens ne passent pas à une nouvelle syntaxe juste parce qu'elle est là

Cela doit me donner quelque chose et je ne vois aucun avantage. Et s'il y a un avantage, les inconvénients sont un fardeau trop grand pour être ignoré.

3 votes

J'ai tendance à utiliser ON parce que c'est moins ambigu que USING ou NATURAL JOIN. Quant aux parenthèses, les personnes qui apprennent "SQL" sur Microsoft Access les utiliseront car Access se plaint si vous les omettez. (Les guillemets autour de SQL devraient être des guillemets de doigts.)

1 votes

Tousse Qu'est-ce qu'une clause USING ? ;-) Je viens de la fraction du serveur SQL, donc ce n'est pas vraiment dans mon radar. Comme l'a dit R. Bemrose, il y a la clause ON, qui fonctionne très bien, ne me laissant jamais avec un joint que je ne pourrais pas exprimer syntaxiquement. Pas besoin d'adapter la conception de ma base de données à la syntaxe de la requête pour économiser quelques frappes.

0 votes

RB & T, oui c'est bien mais ils sont dans le standard. Oh l'humanité, pourquoi?

14voto

Tomalak Points 150423

Quelques raisons viennent à l'esprit :

  • les gens le font par habitude
  • les gens sont paresseux et préfèrent les jointures "à l'ancienne" car elles nécessitent moins de frappe
  • les débutants ont souvent du mal à comprendre la syntaxe de jointure SQL-92
  • les gens ne passent pas à la nouvelle syntaxe simplement parce qu'elle existe
  • les gens ne sont pas conscients des avantages de la nouvelle syntaxe (si on peut l'appeler ainsi), principalement le fait qu'elle vous permet de filtrer une table avant de faire une jointure externe, et non après quand vous n'avez que la clause WHERE.

Pour ma part, je fais toutes mes jointures dans la syntaxe SQL-92, et je convertis le code quand je le peux. C'est la façon la plus propre, lisible et puissante de le faire. Mais il est difficile de convaincre quelqu'un d'utiliser le nouveau style, lorsqu'il pense que cela lui cause plus de travail en termes de frappe sans changer le résultat de la requête.

3 votes

Pour beaucoup de personnes, regarder du SQL leur fait mal. Changer n'importe quel code fonctionnel comporte un risque d'introduire un bug, surtout quand le codeur détourne les yeux. :-)

0 votes

Hm... pour moi, même regarder des expressions régulières complexes ne me fait pas mal du tout. SQL ne peut pas me blesser. ;-)

0 votes

"Les débutants ont souvent des problèmes... " Eh bien, C'EST un argument de vente

11voto

Roger Bold Points 71

En réponse au post sur la jointure NATURELLE et l'utilisation ci-dessus.

POURQUOI auriez-vous jamais besoin d'utiliser ces - 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 spécifierais toujours la table/alias et l'id.

Pour moi, la seule façon de procéder est ANSI-92. C'est plus verbeux et la syntaxe n'est pas appréciée par les partisans d'ANSI-89 mais cela sépare proprement vos JOINTURES de votre FILTRAGE.

0 votes

Je ne vois pas les NATURAL JOINs comme un raccourci, mais comme une passerelle vers la programmation DB orientée objet au sein d'une DB relationnelle.

0 votes

Les joints naturels sont vraiment obscurs et sujets aux erreurs. Évitez-les et dormez bien.

5voto

HLGEM Points 54641

Tout d'abord, laissez-moi dire que dans SQL Server, la syntaxe de jointure externe (*=) ne donne pas toujours des résultats corrects. Il y a des moments où cela est interprété comme une jointure croisée et non comme une jointure externe. C'est une bonne raison d'arrêter de l'utiliser. De plus, cette syntaxe de jointure externe est une fonctionnalité obsolète et ne sera pas présente dans la prochaine version de SQL Server après SQL Server 2008. Vous pourrez toujours réaliser des jointures internes, mais pourquoi diable le feriez-vous? Elles sont confuses et bien plus difficiles à maintenir. Vous ne savez pas facilement ce qui fait partie de la jointure et ce qui est vraiment juste la clause WHERE.

Une raison pour laquelle je pense que vous ne devriez pas utiliser l'ancienne syntaxe est que la compréhension des jointures et de ce qu'elles font ou ne font pas est une étape cruciale pour toute personne amenée à écrire du code SQL. Vous ne devriez pas écrire de code SQL sans bien comprendre les jointures. Si vous les comprenez bien, vous conclurez probablement que la syntaxe ANSI-92 est plus claire et plus facile à maintenir. Je n'ai jamais rencontré d'expert en 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 traité et qui utilisent l'ancien code ne comprennent tout simplement pas les jointures et ont donc des problèmes lorsqu'ils interrogent 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û corriger trop de ces erreurs au fil des ans pour ne pas y croire.

1 votes

Ravi de vous rencontrer. Heureux d'être le premier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X