Aller au contenu

Eclaircissement concernant les jointures


Sujets conseillés

Posté (modifié)

Bonsoir,

Je pose cette question parce que je pense ne pas avoir totalement saisi l'intêret des jointures, et je souhaiterai m'endormir en ayant appris quelque chose de plus, cette nuit :)

A ce que j'ai compris, les jointures permettent d'associer deux tables à partir d'une valeur commune pour en extraire les données. Par exemple :

SELECT nom, prenom,ville,description FROM membres INNER JOIN villes ON membres.ville=ville.nom;

Mais moi, ce que j'ai toujours fait, c'est ça :

SELECT membres.nom, membres.ville, villes.description FROM membres,villes WHERE membres.ville = ville.nom

Soit j'ai pas compris l'intêret (et le fonctionnement) des jointures, soit je provoque de grosses pertes de performances en utilisant ma méthode...

Enfin voilà ! J'aimerai bien savoir :) (et j'ai pas trop compris en lisant la doc)

Merci.

___

Edit : Oups, j'aurai dû poster ce topic dans le forum "SQL".... Toutes mes excuses aux modérateurs :/

Modifié par Silveur
Posté

Bonjour,

SELECT nom, prenom,ville,description FROM membres INNER JOIN villes ON membres.ville=ville.nom;

Premièrement, cette requête (et l'autre également) révèle probablement une erreur lors de la modélisation de ta base de données. Les tables sur lesquelles tu veux faire des jointures doivent avoir une clé primaire (unique) et une ou des clés étrangères, sous la forme d'"INTEGER" (nombre entier), chaque table aura un id et éventuellement une ou plusieurs clés étrangères. Dans ton cas la table membres aura une clé étrangère nommée par exemple ville_id qui fera référence à la table ville qui aura un champ id (unique pour chaque enregistrement).

Les jointures se font sur ces champs et non sur des champs de type "VARCHAR" (comme je suppose ville.nom et membres.ville) et pour au moins deux raisons, lier des tables sur un champs entier est beaucoup plus sûr (pas besoin de s'inquiéter de la collation, l'encodage, etc. car ce sont des entiers) et car sur ces champs il est nécessaire de définir un INDEX (c'est d'ailleurs ainsi qu'il sont "différenciés" des autres) et c'est sur ce point que tu gagnes énormément en performances. Les moteurs de bases de données favorisent un accès rapide aux données qui sont "indexées".

Concernant la deuxième syntaxe qui fonctionne mais dont le but n'est pas tout à fait équivalent et pour citer un bon article sur les types de jointures, dont je te conseille la lecture :

Dans la mesure du possible, utilisez toujours un opérateur de jointure normalisé Sql2 (mot clef JOIN).

En effet :

  • Les jointures faites dans la clause WHERE (ancienne syntaxe de 1986 !) ne permettent pas de faire la distinction de prime abord entre ce qui relève du filtrage et ce qui relève de la jointure.
  • Il est à priori absurde de vouloir filtrer dans le WHERE (ce qui restreint les données du résultat) et de voiloir "élargir" ce résultat par une jointure dans la même clause WHERE de filtrage.
  • La lisibilité des requêtes est plus grande en utilisant la syntaxe à base de JOIN, en isolant ce qui est du filtrage et de la jointure, mais aussi en isolant avec clarté chaque condition de jointures entre chaque couples de table.
  • L'optimisation d'exécution de la requête est souvent plus pointue du fait de l'utilisation du JOIN.
  • Lorsque l'on utilise l'ancienne syntaxe et que l'on supprime la clause WHERE a des fins de tests, le moteur SQL réalise le produit cartésiens des tables ce qui revient la plupart du temps à mettre à genoux le serveur !

Source : Le SQL de A à Z - le SELECT sur plusieurs tables

Bonne continuation.

Posté
une clé étrangère nommée par exemple ville_id qui fera référence à la table ville qui aura un champ id (unique pour chaque enregistrement).

Les jointures se font sur ces champs et non sur des champs de type "VARCHAR"

Ce principe est très sûr en termes de performances, mais de mon point de vue, une jointure faite sur un champs varchar avec une contrainte d'unicité et une indexation (par exemple un champs référence) sera tout aussi performante.

La clé étrangère sur la table garantit en plus l'intégrité des deux tables en cas de suppression d'enregistrement, par exemple.

Mais elle n'est pas absolument nécessaire pour une bonne jointure.

Pour le reste, 100 % d'accord avec Therec.

Posté
Ce principe est très sûr en termes de performances, mais de mon point de vue, une jointure faite sur un champs varchar avec une contrainte d'unicité et une indexation (par exemple un champs référence) sera tout aussi performante.

C'est discutable dans la mesure ou l'allocation mémoire d'un champ VARCHAR est faite selon la longueur de son contenu (plus un octet, pour stocker cette longueur), donc plus ton champ va occuper de mémoire, plus l'INDEX aura de données à traiter (sur des quantités de données cela a un impact). Il est possible d'indexer un préfix sur ce type de champs (CHAR et VARCHAR), mais cela ne résout pas les inconvénient que j'ai cités précédemment (collation, encodage... ceux-ci sont réglés sans problèmes avec les entiers, car la représentation est la même quel que soit l'encodage et/ou la collation).

Mais cela reste une pratique possible... je ne me vois juste pas la conseiller ;) C'est vrai que j'aurais du être moins catégorique et ajouter "généralement" dans cette phrase.

Posté
Ce principe est très sûr en termes de performances, mais de mon point de vue, une jointure faite sur un champs varchar avec une contrainte d'unicité et une indexation (par exemple un champs référence) sera tout aussi performante.

La clé étrangère sur la table garantit en plus l'intégrité des deux tables en cas de suppression d'enregistrement, par exemple.

Mais elle n'est pas absolument nécessaire pour une bonne jointure.

Pour le reste, 100 % d'accord avec Therec.

Cela dit, en répétant inutilement plusieurs fois la même données, c'est surtout une question de place occupée. De plus, je suis quand même assez sceptique sur les performances. L'utilisation d'index numériques, plus petits que des noms de villes en varchar, sera beaucoup plus efficace.

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...