Aller au contenu principal

Workshop, les arbres algébriques

Ce que ce chapitre apporte

  • Employer chaque opérateur fondamental isolément, puis en combinaison.
  • Choisir l'ordre d'application des opérations, et savoir lequel est imposé.
  • Lire un arbre algébrique et le construire à partir d'un énoncé en français.
  • Réécrire un arbre en un arbre équivalent qui travaille moins.

Un chapitre entièrement d'exercices. Chaque énoncé se traite dans le même ordre : lire la question en français, écrire l'expression algébrique, la dessiner en arbre, puis la pousser vers une forme moins coûteuse. Les corrigés sont repliés et calculés : chaque arbre affiché se clique, nœud par nœud, pour voir la relation qu'il produit. Les ouvrir après avoir cherché, pas avant.

Le contrat de chaque exercice

Ce que chaque énoncé garantit
  • L'énoncé donne les données sur lesquelles travailler, ou renvoie explicitement à la base de démonstration du module.
  • Il se termine par une ligne Vérification : le nombre de lignes et de colonnes que rend l'expression juste. Elle tient le rôle des assert des ateliers de programmation. Une expression qui ne rend pas ce compte est fausse, même si elle semble dire la bonne chose.
  • La correction est repliée sous l'énoncé. Chaque arbre qu'elle contient se clique nœud par nœud, et affiche la relation produite à cet étage : c'est là qu'on voit à quel moment une expression dérape.
  • Chercher d'abord, comparer à la ligne Vérification, ouvrir la correction ensuite. Les trois niveaux se suivent, chacun supposant le précédent traité.

Déroulé

Temps indicatifNiveauCe qui est travaillé
30 minNiveau 1, exercices 1 à 5un opérateur à la fois : σ, π, ∪, −, ×
45 minNiveau 2, exercices 6 à 9enchaîner plusieurs opérations, et poser une division
45 minNiveau 3, exercices 10 à 14lire un arbre, en construire un, le réécrire moins coûteux

Prévoir environ deux heures pour l'ensemble, corrections comprises.

Rappel des notations

OpérateurSymboleEffet
Sélectionσfiltre les lignes selon une condition
Projectionπne garde que certaines colonnes, et dédoublonne
Renommageρchange le nom d'un attribut
Unionréunit deux relations de même schéma, sans doublon
Intersectionne garde que ce qui figure des deux côtés
Différenceretire de la gauche ce que porte la droite
Produit cartésien×toutes les combinaisons de lignes
Jointureproduit filtré par une condition d'appariement
Division÷ce qui est lié à tous les éléments d'une autre relation
Dans quel sens lire une expression emboîtée

Une expression s'évalue de l'intérieur vers l'extérieur, comme en mathématiques.

Dans π_{nom}(σ_{ville = 'Paris'}(Client)), lire d'abord Client, puis la sélection, puis la projection. Sur l'arbre, cela revient à partir des feuilles et à remonter jusqu'à la racine.

Niveau 1, un opérateur à la fois

Ces exercices portent sur les opérateurs de base, isolément. L'objectif est la syntaxe et l'effet exact de chaque opération sur les lignes et sur les colonnes.

Exercice 1, sélection

Relation Produit :

idProduitnomprix
1Clavier45
2Souris30
3Ecran220
  1. Écrire une expression qui garde uniquement les produits dont le prix dépasse strictement 40.
  2. Nommer les produits retenus.
  3. Modifier l'expression pour garder ceux dont le prix ne dépasse pas 100.

Vérification. Les deux expressions rendent chacune deux lignes et gardent les trois colonnes. Ce ne sont pas les deux mêmes lignes.

Afficher la correction

La sélection filtre les lignes et laisse le schéma intact : les trois colonnes restent.

Cliquer sur un nœud pour voir la relation qu'il produit.

σ prix > 40σ prix > 40ProduitProduit
σ prix > 402 lignes · 3 attributs
idProduitnomprix
1Clavier45
3Ecran220
Clavier et Ecran passent. Souris est écartée : 30 n'est pas supérieur à 40.

Pour la seconde condition, seul le comparateur change.

Cliquer sur un nœud pour voir la relation qu'il produit.

σ prix ≤ 100σ prix ≤ 100ProduitProduit
σ prix ≤ 1002 lignes · 3 attributs
idProduitnomprix
1Clavier45
2Souris30
Ecran sort à son tour : 220 dépasse 100. Les deux autres restent.

Exercice 2, projection

Toujours avec Produit :

  1. Écrire une projection qui ne garde que nom et prix.
  2. Une projection peut-elle réduire le nombre de lignes ? Justifier.
  3. Écrire une projection qui ne garde que idProduit.

Vérification. Sur les trois produits ci-dessus, les deux projections rendent trois lignes, l'une sur deux colonnes, l'autre sur une seule. La question 2 porte sur le cas, absent de cette table, où ce compte tomberait plus bas.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prixπ nom, prixProduitProduit
π nom, prix3 lignes · 2 attributs
nomprix
Clavier45
Souris30
Ecran220
La colonne idProduit disparaît, les trois lignes subsistent.

Oui, une projection peut réduire le nombre de lignes. Une relation est un ensemble : si la projection efface ce qui distinguait deux lignes, elles se confondent. Il suffit d'ajouter une seconde souris au même prix pour le voir.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prixπ nom, prixProduitProduit
π nom, prix3 lignes · 2 attributs
nomprix
Clavier45
Souris30
Ecran220
Quatre produits, trois lignes. Les deux souris à 30 sont devenues indiscernables une fois idProduit retiré.

Sur idProduit, qui est une clé, aucune fusion n'est possible.

Cliquer sur un nœud pour voir la relation qu'il produit.

π idProduitπ idProduitProduitProduit
π idProduit3 lignes · 1 attribut
idProduit
1
2
3
Une clé ne contient jamais deux fois la même valeur : les trois lignes restent trois.

Exercice 3, union

Deux relations de même schéma. Client(nom) contient Alice et Bernard ; Prospect(nom) contient Bernard et Camille.

  1. Écrire l'expression qui rassemble tous les noms présents dans l'une ou l'autre.
  2. Donner le résultat attendu, nom par nom.
  3. Dire ce qui se passe si les deux relations n'ont pas les mêmes colonnes.

Vérification. Quatre lignes entrent, trois sortent.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

ClientClientProspectProspect
3 lignes · 1 attribut
nom
Alice
Bernard
Camille
Trois noms pour quatre lignes en entrée. Bernard figurait des deux côtés et n'apparaît qu'une fois.

L'union est une opération ensembliste : elle exige le même schéma, c'est-à-dire le même nombre d'attributs, dans le même ordre, de types compatibles. Sans cela, on ne saurait pas quelle colonne du résultat correspond à quoi. Le moteur refuse l'opération.

Exercice 4, différence

Mêmes relations.

  1. Écrire l'expression qui garde les clients qui ne sont pas aussi prospects.
  2. Donner le résultat.
  3. La différence est-elle symétrique ? Justifier par un exemple.

Vérification. Une seule ligne dans un sens, une seule dans l'autre, et ce n'est pas la même.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

ClientClientProspectProspect
1 ligne · 1 attribut
nom
Alice
Alice seule. Bernard est les deux à la fois, il est donc retiré.

Non, la différence n'est pas symétrique. L'inverse donne un résultat entièrement différent.

Cliquer sur un nœud pour voir la relation qu'il produit.

ProspectProspectClientClient
1 ligne · 1 attribut
nom
Camille
Camille seule. Même données, ordre inversé, résultat sans aucune ligne commune avec le précédent.

L'union, elle, est symétrique : A ∪ B et B ∪ A donnent la même relation.

Exercice 5, produit cartésien

Auteur(nom) contient Camus et Duras. Livre(titre) contient La Peste, L Etranger et Le Ravissement.

  1. Écrire le produit cartésien des deux.
  2. Dire combien de lignes le résultat compte, et pourquoi ce compte ne dépend pas des données.
  3. Expliquer pourquoi ce produit devient une jointure utile une fois filtré.

Vérification. Six lignes et deux colonnes.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

××AuteurAuteurLivreLivre
×6 lignes · 2 attributs
nomtitre
CamusLa Peste
CamusL Etranger
CamusLe Ravissement
DurasLa Peste
DurasL Etranger
DurasLe Ravissement
2 × 3 = 6 lignes. Toutes les combinaisons, y compris celles qui n'ont aucun sens.

Le produit associe tout à tout, sans se soucier de ce qui va ensemble. Il n'a donc aucune signification métier tel quel. En lui appliquant une sélection qui ne retient que les paires réellement liées, on obtient exactement une jointure :

R ⨝_{condition} S  =  σ_{condition}(R × S)

C'est la définition de la jointure, et la raison pour laquelle le produit cartésien mérite d'être compris malgré son inutilité apparente.

Niveau 2, combiner les opérateurs

Les exercices suivants enchaînent plusieurs opérations. La question devient : dans quel ordre ? Certains ordres sont imposés par la disponibilité des colonnes ; parmi ceux qui restent, tous ne coûtent pas la même chose.

À partir d'ici, les exercices portent sur la base de démonstration du module, celle des chapitres SQL. Les résultats affichés sont donc ceux que rendraient les requêtes correspondantes.

Exercice 6, jointure simple

Relations Employe(idEmploye, nom, prenom, salaire, date_embauche, service) et, côté projets, TravailleSur(idEmploye, idProjet, heures) et Projet(idProjet, libelle, idClient).

  1. Écrire une expression qui associe à chaque affectation le libellé du projet concerné.
  2. Expliquer pourquoi une union ne conviendrait pas ici.
  3. Réécrire l'expression pour ne garder que le nom de l'employé et le libellé du projet.

Vérification. La première expression rend sept lignes et six colonnes, la troisième sept lignes et deux colonnes.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

⨝ TravailleSur.idProjet = Pro…⨝ TravailleSur.idProjet = Projet.idProjetTravailleSurTravailleSurProjetProjet
⨝ TravailleSur.idProjet = Projet.idProjet7 lignes · 6 attributs
idEmployeTravailleSur.idProjetheuresProjet.idProjetlibelleidClient
111201Portail client1
13403Application mobile3
21801Portail client1
322002Refonte ERP2
33603Application mobile3
44354Audit reseau4
52902Refonte ERP2
Chaque affectation est enrichie du libellé de son projet. Les sept lignes de TravailleSur sont conservées, chacune trouvant son projet. En SQL : SELECT * FROM TravailleSur JOIN Projet ON TravailleSur.idProjet = Projet.idProjet

Une union est impossible : elle exige deux relations de même schéma, or TravailleSur a trois attributs et Projet trois autres, qui ne désignent pas les mêmes choses. La jointure, elle, est faite pour rapprocher des relations de schémas différents partageant une valeur.

Pour obtenir le nom de l'employé, une seconde jointure est nécessaire, puisque TravailleSur ne porte qu'un identifiant.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, libelleπ nom, libelle⨝ TravailleSur.idProjet = Pro…⨝ TravailleSur.idProjet = Projet.idProjet⨝ Employe.idEmploye = Travail…⨝ Employe.idEmploye = TravailleSur.idEmployeEmployeEmployeTravailleSurTravailleSurProjetProjet
π nom, libelle7 lignes · 2 attributs
nomlibelle
GirardPortail client
GirardApplication mobile
LemoinePortail client
BarbierRefonte ERP
BarbierApplication mobile
RocheAudit reseau
VidalRefonte ERP
Sept affectations, sept lignes. Girard et Barbier apparaissent deux fois : elles travaillent sur deux projets. En SQL : SELECT DISTINCT nom, libelle FROM Employe JOIN TravailleSur ON Employe.idEmploye = TravailleSur.idEmploye JOIN Projet ON TravailleSur.idProjet = Projet.idProjet

Exercice 7, sélection et jointure

Objectif : le nom des employés affectés au projet Refonte ERP.

  1. Écrire l'expression complète.
  2. Expliquer pourquoi la sélection sur le libellé ne peut pas s'appliquer directement à TravailleSur.
  3. Proposer une version qui filtre avant de joindre, et dire ce qu'elle gagne.

Vérification. Deux lignes et une colonne, dans les deux versions. Ce qui change est la taille du nœud de jointure le plus large : sept lignes d'un côté, deux de l'autre.

Afficher la correction

Première écriture, la plus directe : joindre les trois tables, puis filtrer.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nomσ libelle = 'Refonte ERP'σ libelle = 'Refonte ERP'⨝ TravailleSur.idProjet = Pro…⨝ TravailleSur.idProjet = Projet.idProjet⨝ Employe.idEmploye = Travail…⨝ Employe.idEmploye = TravailleSur.idEmployeEmployeEmployeTravailleSurTravailleSurProjetProjet
π nom2 lignes · 1 attribut
nom
Barbier
Vidal
Version directe. La jointure du haut construit 7 lignes avant que la sélection n'en garde 2.

L'attribut libelle n'existe que dans Projet. Tant que la jointure n'a pas eu lieu, aucune ligne de TravailleSur ne le porte, et la sélection n'a rien sur quoi s'appliquer. L'ordre est donc imposé ici : joindre Projet avant de filtrer sur libelle.

En revanche, rien n'oblige à joindre Projet en dernier. Filtrer Projet d'abord, puis joindre, donne le même résultat pour beaucoup moins de travail.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nom⨝ Employe.idEmploye = Travail…⨝ Employe.idEmploye = TravailleSur.idEmployeEmployeEmploye⨝ TravailleSur.idProjet = Pro…⨝ TravailleSur.idProjet = Projet.idProjetTravailleSurTravailleSurσ libelle = 'Refonte ERP'σ libelle = 'Refonte ERP'ProjetProjet
π nom2 lignes · 1 attribut
nom
Barbier
Vidal
Version optimisée. La sélection descend sur la feuille Projet : une seule ligne à droite, et plus aucune ligne intermédiaire inutile.

C'est le principe de la poussée de sélection : la condition descend le long de l'arbre jusqu'à la feuille dont elle dépend.

Exercice 8, division

EmployeCompetence(employe, competence) contient les couples Alice-Java, Alice-SQL, Alice-Reseau, Paul-Java, Paul-SQL et Chi-Java. Competence(competence) contient Java et SQL.

  1. Écrire une expression qui identifie les employés possédant toutes les compétences listées.
  2. Dire ce que cette opération permet et que les autres ne permettent pas.
  3. Expliquer pourquoi Chi est exclue, et pourquoi Alice ne l'est pas malgré sa compétence supplémentaire.

Vérification. Deux lignes et une seule colonne, employe.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

÷÷EmployeCompetenceEmployeCompetenceCompetenceCompetence
÷2 lignes · 1 attribut
employe
Alice
Paul
Alice et Paul possèdent Java et SQL. Chi n'a que Java, elle est exclue. Que Alice ait Reseau en plus ne change rien.

La division exprime une quantification universelle : « pour tout élément du diviseur, il existe une association dans le dividende ». Ni la sélection ni la jointure ne savent dire « tous ». Une jointure répondrait à « au moins un », ce qui est une question différente.

SQL n'a pas de mot-clé pour la division. On la traduit par une double négation : les employés pour lesquels il n'existe pas de compétence de la liste qu'ils ne possèdent pas.

Chi est exclue parce qu'il existe une compétence de la liste, SQL, qu'elle ne possède pas. Une seule manquante suffit.

Exercice 9, jointure et division

Objectif : le nom des étudiants inscrits à tous les cours de coefficient 1,5.

  1. Écrire l'expression, en deux étapes.
  2. Dire pourquoi la division est indispensable.
  3. Expliquer pourquoi une projection doit précéder la division.

Vérification. La division rend une ligne. L'expression complète rend une ligne et deux colonnes.

Afficher la correction

Première étape, identifier les cours concernés, puis diviser.

Cliquer sur un nœud pour voir la relation qu'il produit.

÷÷π idEtudiant, idCoursπ idEtudiant, idCoursInscriptionInscriptionπ idCoursπ idCoursσ coefficient = 1.5σ coefficient = 1.5CoursCours
÷1 ligne · 1 attribut
idEtudiant
3
Deux cours ont le coefficient 1,5. Un seul étudiant est inscrit aux deux.

Seconde étape, récupérer le nom par une jointure sur l'identifiant obtenu.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prenomπ nom, prenom⨝ naturelle⨝ naturelleEtudiantEtudiant÷÷π idEtudiant, idCoursπ idEtudiant, idCoursInscriptionInscriptionπ idCoursπ idCoursσ coefficient = 1.5σ coefficient = 1.5CoursCours
π nom, prenom1 ligne · 2 attributs
nomprenom
DupondSophie
Le résultat de la division est une relation comme les autres : elle se joint à Etudiant pour retrouver le nom.

La division est indispensable parce que la question porte sur tous les cours. Une jointure seule rendrait les étudiants inscrits à au moins un de ces cours, ce qui est une réponse différente et plus large.

La projection avant la division n'est pas décorative

Inscription porte trois attributs : idEtudiant, idCours et note. Écrire directement Inscription ÷ π_{idCours}(Cours) ferait entrer note dans le calcul : le résultat serait constitué de couples (idEtudiant, note) couvrant tous les cours, autrement dit d'étudiants ayant obtenu exactement la même note dans tous les cours de la liste.

La projection sur les deux seuls attributs utiles évite cette confusion. C'est la règle générale : avant une division, réduire le dividende aux attributs concernés.

Niveau 3, les arbres

Un arbre algébrique est le dessin d'une expression. La racine porte l'opération finale, les feuilles sont les tables, les nœuds internes les opérations intermédiaires. Il se lit de bas en haut.

Les deux règles de réécriture

Descendre les sélections au plus près des feuilles, et descendre les projections dès que les attributs supérieurs le permettent. Les deux disent la même chose : réduire tôt ce qui sera réduit de toute façon, pour que les opérations coûteuses travaillent sur moins.

Exercice 10, lecture d'un arbre

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prenomπ nom, prenomσ ville = 'Paris'σ ville = 'Paris'ClientClient
π nom, prenom2 lignes · 2 attributs
nomprenom
DurandPaul
MoreauKarim
Que fait cet arbre ? Cliquer sur les nœuds de bas en haut.
  1. Décrire étape par étape ce que fait cet arbre.
  2. Dire ce qui se passe si la projection et la sélection sont inversées.
  3. Conclure sur l'interchangeabilité des deux opérations.

Vérification. L'arbre donné rend deux lignes et deux colonnes. L'arbre inversé n'en rend aucune : il échoue, et c'est précisément la réponse à la question 2.

Afficher la correction

De bas en haut : partir de Client (quatre lignes), ne garder que les clients parisiens (deux lignes), puis n'afficher que le nom et le prénom.

Inversées, l'expression devient σ_{ville = 'Paris'}(π_{nom, prenom}(Client)). Après la projection, la colonne ville a disparu : la sélection n'a plus rien sur quoi porter.

Cliquer sur un nœud pour voir la relation qu'il produit.

σ ville = 'Paris'σ ville = 'Paris'π nom, prenomπ nom, prenomClientClient
σ ville = 'Paris'

Échec attendu.attribut inconnu : ville. Disponibles : nom, prenom

L'arbre s'analyse, mais le nœud de sélection échoue : ville n'existe plus à ce niveau. Cliquer dessus pour lire le message.

Les deux opérations ne sont donc pas librement interchangeables. Une projection ne peut descendre sous une sélection que si elle conserve les attributs dont cette sélection a besoin. En pratique, on descend les projections en gardant les colonnes utilisées plus haut, quitte à les projeter une seconde fois à la racine.

Exercice 11, construire un arbre simple

Objectif : le nom et le prénom des clients ayant au moins un projet.

  1. Donner l'expression algébrique.
  2. Décrire l'arbre correspondant.
  3. Nommer l'opération centrale et dire pourquoi elle est nécessaire.

Vérification. Quatre lignes et deux colonnes.

Afficher la correction

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prenomπ nom, prenom⨝ Client.idClient = Projet.id…⨝ Client.idClient = Projet.idClientClientClientProjetProjet
π nom, prenom4 lignes · 2 attributs
nomprenom
DurandPaul
LeroySarah
MoreauKarim
FontaineEva
Deux feuilles reliées par une jointure, surmontées d'une projection. En SQL : SELECT DISTINCT nom, prenom FROM Client JOIN Projet ON Client.idClient = Projet.idClient

L'opération centrale est la jointure. Sans elle, l'information reste séparée : Projet ne contient pas le nom du client, Client ne contient pas la liste de ses projets. Seul l'identifiant partagé permet de les rapprocher.

Noter que la jointure fait ici un travail de filtre en plus de son travail d'appariement. Un client sans aucun projet ne figurerait pas dans le résultat, aucune ligne de Projet ne lui correspondant.

Exercice 12, sélection et jointures multiples

Objectif : le nom des étudiants inscrits au cours Mathematiques.

  1. Donner une expression complète.
  2. Décrire l'arbre non optimisé.
  3. Proposer une version optimisée et expliquer le gain.

Vérification. Cinq lignes et une colonne, dans les deux versions. Le nœud le plus large passe de vingt-cinq lignes à cinq.

Afficher la correction

Version non optimisée : joindre les trois tables, puis filtrer sur l'intitulé.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nomσ intitule = 'Mathematiques'σ intitule = 'Mathematiques'⨝ Inscription.idCours = Cours…⨝ Inscription.idCours = Cours.idCours⨝ Etudiant.idEtudiant = Inscr…⨝ Etudiant.idEtudiant = Inscription.idEtudiantEtudiantEtudiantInscriptionInscriptionCoursCours
π nom5 lignes · 1 attribut
nom
Martin
Diallo
Dupond
Bernard
Nguyen
Version non optimisée. La jointure du haut construit 25 lignes, dont la sélection n'en garde que 5.

Version optimisée : filtrer Cours avant de joindre. La sélection descend jusqu'à la feuille dont elle dépend.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nom⨝ Etudiant.idEtudiant = Inscr…⨝ Etudiant.idEtudiant = Inscription.idEtudiantEtudiantEtudiant⨝ Inscription.idCours = Cours…⨝ Inscription.idCours = Cours.idCoursInscriptionInscriptionσ intitule = 'Mathematiques'σ intitule = 'Mathematiques'CoursCours
π nom5 lignes · 1 attribut
nom
Martin
Diallo
Dupond
Bernard
Nguyen
Version optimisée. Cours est réduit à une ligne avant la jointure, qui n'en produit plus que 5 au lieu de 25.

Le résultat est identique. Le nœud le plus large passe de 25 à 5 lignes, et l'écart croît avec la taille de la base. Sur mille cours et cent mille inscriptions, la première version construit cent mille lignes intermédiaires pour en garder quelques dizaines.

Exercice 13, lire et transformer

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nomσ nomClasse = '2A'σ nomClasse = '2A'⨝ Etudiant.idClasse = Classe…⨝ Etudiant.idClasse = Classe.idClasseEtudiantEtudiantClasseClasse
π nom3 lignes · 1 attribut
nom
Moreau
Marchand
Nguyen
L'arbre de départ.
  1. Nommer les nœuds internes et les feuilles.
  2. Dire ce qu'il faudrait changer pour afficher aussi le prénom.
  3. Dire ce qu'il faudrait changer pour filtrer sur le prénom au lieu du nom de classe.

Vérification. L'arbre de départ rend trois lignes et une colonne. Avec le prénom ajouté, trois lignes et deux colonnes. En filtrant sur prenom = 'Chi', une seule ligne.

Afficher la correction

Les feuilles sont Etudiant et Classe. Les nœuds internes sont la jointure et la sélection. La racine est la projection π_{nom}.

Pour afficher aussi le prénom, seule la projection change. prenom appartient déjà à Etudiant, qui figure dans l'arbre : rien d'autre à toucher.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, prenomπ nom, prenomσ nomClasse = '2A'σ nomClasse = '2A'⨝ Etudiant.idClasse = Classe…⨝ Etudiant.idClasse = Classe.idClasseEtudiantEtudiantClasseClasse
π nom, prenom3 lignes · 2 attributs
nomprenom
MoreauChi
MarchandHugo
NguyenElsa
Un seul nœud modifié, la racine.

Pour filtrer sur le prénom, la situation est meilleure qu'il n'y paraît. prenom appartient à Etudiant, donc la sélection n'a pas besoin d'attendre la jointure : elle peut descendre directement sur la feuille.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nom, nomClasseπ nom, nomClasse⨝ Etudiant.idClasse = Classe…⨝ Etudiant.idClasse = Classe.idClasseσ prenom = 'Chi'σ prenom = 'Chi'EtudiantEtudiantClasseClasse
π nom, nomClasse1 ligne · 2 attributs
nomnomClasse
Moreau2A
La sélection est descendue sur Etudiant : la jointure ne voit plus qu'une ligne à gauche au lieu de dix.

C'est la différence entre les deux cas. nomClasse vient de Classe, donc une sélection dessus doit se placer au-dessus de la jointure ou sur la feuille Classe. prenom vient de Etudiant : sa sélection descend de l'autre côté.

Exercice 14, d'un besoin à un arbre

Objectif : le nom des employés du service Etudes ayant travaillé plus de 100 heures sur un projet.

  1. Lister les opérations nécessaires, dans l'ordre logique.
  2. Donner l'expression complète, déjà optimisée.
  3. Décrire l'arbre obtenu.

Vérification. Deux lignes et une colonne. La version bien ordonnée fait travailler la jointure sur deux lignes de chaque côté, la version naïve sur cinq et sept.

Afficher la correction

Les opérations, dans l'ordre :

  1. filtrer les employés du service Etudes, sur la feuille Employe ;
  2. filtrer les affectations de plus de 100 heures, sur la feuille TravailleSur ;
  3. joindre les deux résultats sur idEmploye ;
  4. projeter le nom.

Les deux sélections sont indépendantes et portent chacune sur une feuille différente : elles descendent toutes les deux.

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nom⨝ Employe.idEmploye = Travail…⨝ Employe.idEmploye = TravailleSur.idEmployeσ service = 'Etudes'σ service = 'Etudes'EmployeEmployeσ heures > 100σ heures > 100TravailleSurTravailleSur
π nom2 lignes · 1 attribut
nom
Girard
Barbier
Deux sélections sur les deux feuilles, une jointure qui ne voit plus que 2 lignes à gauche et 2 à droite, une projection à la racine.

Pour mesurer le gain, la même question écrite sans réfléchir à l'ordre :

Cliquer sur un nœud pour voir la relation qu'il produit.

π nomπ nomσ service = 'Etudes' ∧ heures…σ service = 'Etudes' ∧ heures > 100⨝ Employe.idEmploye = Travail…⨝ Employe.idEmploye = TravailleSur.idEmployeEmployeEmployeTravailleSurTravailleSur
π nom2 lignes · 1 attribut
nom
Girard
Barbier
Même résultat, mais la jointure construit d'abord les 7 affectations avant qu'on en jette 5.

Les deux arbres rendent les deux mêmes lignes. Le premier fait travailler la jointure sur deux lignes de chaque côté, le second sur cinq et sept. Sur une base réelle, ce rapport est celui de la sélectivité des deux filtres, et il se compte souvent en ordres de grandeur.

La méthode

  1. Lire l'énoncé et repérer le mot qui porte la question : « seulement ceux qui » appelle une sélection, « le nom de » une projection, « et son » une jointure, « tous les » une division.
  2. Lister les tables nécessaires et vérifier, attribut par attribut, laquelle porte chaque colonne citée par l'énoncé. Une colonne sans table est le signe qu'il manque une jointure.
  3. Poser les jointures d'abord, chacune avec sa condition d'appariement écrite en toutes lettres.
  4. Placer chaque sélection sur la feuille dont elle dépend. Ne laisser au-dessus de la jointure que les conditions qui mélangent deux tables.
  5. Projeter en dernier, en n'écrivant que les attributs demandés, et se rappeler que la projection dédoublonne.
  6. Compter le résultat à la main et le comparer à la ligne Vérification de l'énoncé, avant d'ouvrir la correction.
  7. Cliquer le nœud le plus large de l'arbre et chercher l'opération qui le ferait rétrécir. Recommencer tant qu'il en reste une.

Synthèse

  • σ agit sur les lignes et laisse le schéma intact. π agit sur les colonnes, et peut réduire le nombre de lignes par dédoublonnage, puisqu'une relation est un ensemble.
  • ∪, ∩ et − exigent deux relations de même schéma. Seule la différence dépend de l'ordre de ses opérandes.
  • × associe tout à tout et n'a aucun sens métier tel quel. Une sélection posée dessus en fait exactement une jointure, ce qui est sa définition.
  • ⨝ rapproche deux schémas différents sur une valeur partagée, et écarte au passage ce qui ne s'apparie pas : c'est un filtre autant qu'un assemblage.
  • ÷ traduit un « pour tous ». Réduire le dividende par une projection aux seuls attributs concernés, sans quoi la question posée change en silence.
  • Un ordre est imposé quand une opération réclame un attribut qu'une autre produit ou détruit : filtrer sur libelle exige d'avoir joint Projet, filtrer sur ville interdit d'avoir déjà projeté sans elle.
  • Parmi les ordres possibles, tous ne coûtent pas la même chose. Une sélection descend jusqu'à la feuille dont elle dépend ; une projection descend tant que les opérations supérieures n'ont plus besoin des colonnes retirées.
  • Un arbre se lit de bas en haut : les feuilles sont les tables, les nœuds internes les opérations, la racine le résultat rendu.
  • Deux arbres équivalents se comparent au nombre de lignes de leur nœud le plus large, jamais à leur résultat, qui est le même par construction.

Quiz

Vérification rapideon peut se reprendre

1.π_{nom, prix}(Produit) peut-il rendre moins de lignes que Produit ?

2.Pourquoi une union entre Employe et Projet est-elle impossible ?

3.σ_{ville = 'Paris'}(π_{nom, prenom}(Client)) échoue. Pourquoi ?

4.Dans π_{nom}(σ_{libelle = 'Refonte ERP'}(TravailleSur ⨝ Projet)), la sélection peut-elle descendre sous la jointure ?

5.Avant une division, pourquoi projeter le dividende ?

6.Une jointure entre Client et Projet écarte-t-elle un client sans projet ?

7.Deux arbres donnent le même résultat. Le premier a un nœud à 25 lignes, le second à 5. Que conclure ?