Partie 3 : Fusion de tables
1. Pourquoi fusionner des tables ?
Section intitulée « 1. Pourquoi fusionner des tables ? »1.1 Le problème de la redondance
Section intitulée « 1.1 Le problème de la redondance »Imaginons qu'on veuille stocker les résultats des élèves avec les informations de leur classe. Si on met tout dans une seule table, les informations de classe sont répétées pour chaque élève :
| Nom | Classe | Professeur principal | Salle | Note |
|---|---|---|---|---|
| Dupont | 1NSI-A | M. Duval | 204 | 15 |
| Martin | 1NSI-A | M. Duval | 204 | 12 |
| Durand | 1NSI-B | Mme Leroux | 108 | 18 |
| Petit | 1NSI-A | M. Duval | 204 | 9 |
Les informations « M. Duval » et « 204 » sont répétées trois fois. C'est de la redondance.
1.2 La solution : séparer les données
Section intitulée « 1.2 La solution : séparer les données »On sépare en deux tables reliées par un attribut commun (la clé) :
Table eleves :
| Nom | Classe | Note |
|---|---|---|
| Dupont | 1NSI-A | 15 |
| Martin | 1NSI-A | 12 |
| Durand | 1NSI-B | 18 |
| Petit | 1NSI-A | 9 |
Table classes :
| Classe | Professeur principal | Salle |
|---|---|---|
| 1NSI-A | M. Duval | 204 |
| 1NSI-B | Mme Leroux | 108 |
L'attribut Classe est présent dans les deux tables : c'est la clé de jointure. Dans la table eleves, on l'appelle clé étrangère car elle fait référence à une entrée d'une autre table.
2. La jointure
Section intitulée « 2. La jointure »2.1 Principe
Section intitulée « 2.1 Principe »La jointure (ou fusion) consiste à combiner les lignes de deux tables qui partagent une même valeur pour un attribut commun.
Pour chaque ligne de la première table, on cherche la ligne correspondante dans la seconde table (celle qui a la même valeur de clé), et on fusionne les deux.
2.2 Exemple en Python
Section intitulée « 2.2 Exemple en Python »eleves = [ {"nom": "Dupont", "classe": "1NSI-A", "note": 15}, {"nom": "Martin", "classe": "1NSI-A", "note": 12}, {"nom": "Durand", "classe": "1NSI-B", "note": 18}, {"nom": "Petit", "classe": "1NSI-A", "note": 9}]
classes = [ {"classe": "1NSI-A", "prof": "M. Duval", "salle": 204}, {"classe": "1NSI-B", "prof": "Mme Leroux", "salle": 108}]
def jointure(table1, table2, cle): """Fusionne deux tables sur un attribut commun.""" resultat = [] for ligne1 in table1: for ligne2 in table2: if ligne1[cle] == ligne2[cle]: fusion = {} fusion.update(ligne1) fusion.update(ligne2) resultat.append(fusion) return resultat
table_complete = jointure(eleves, classes, "classe")for e in table_complete: print(e)Résultat :
{"nom": "Dupont", "classe": "1NSI-A", "note": 15, "prof": "M. Duval", "salle": 204}{"nom": "Martin", "classe": "1NSI-A", "note": 12, "prof": "M. Duval", "salle": 204}{"nom": "Durand", "classe": "1NSI-B", "note": 18, "prof": "Mme Leroux", "salle": 108}{"nom": "Petit", "classe": "1NSI-A", "note": 9, "prof": "M. Duval", "salle": 204}2.3 Fonctionnement détaillé
Section intitulée « 2.3 Fonctionnement détaillé »Pour chaque élève, on parcourt toutes les classes pour trouver celle qui a la même valeur de "classe". Quand on la trouve, on fusionne les deux dictionnaires :
Dupont (1NSI-A) + classe 1NSI-A (M. Duval, 204) → fusionMartin (1NSI-A) + classe 1NSI-A (M. Duval, 204) → fusionDurand (1NSI-B) + classe 1NSI-B (Mme Leroux, 108) → fusionPetit (1NSI-A) + classe 1NSI-A (M. Duval, 204) → fusion3. Cas particuliers
Section intitulée « 3. Cas particuliers »3.1 Lignes sans correspondance
Section intitulée « 3.1 Lignes sans correspondance »Si un élève a une classe qui n'existe pas dans la table classes, il ne sera pas inclus dans le résultat de la jointure :
eleves = [ {"nom": "Dupont", "classe": "1NSI-A", "note": 15}, {"nom": "Moreau", "classe": "1NSI-C", "note": 14} # classe inconnue]
# Moreau n'apparait pas dans le résultat car "1NSI-C" n'est pas dans classesC'est le comportement standard de la jointure : seules les lignes ayant une correspondance dans les deux tables sont conservées.
3.2 Attributs en conflit
Section intitulée « 3.2 Attributs en conflit »Si les deux tables ont un attribut de même nom (autre que la clé), la valeur de la seconde table écrase celle de la première (avec update()). Pour l'éviter, on peut renommer les attributs :
def jointure_safe(table1, table2, cle): """Jointure avec préfixe pour éviter les conflits.""" resultat = [] for l1 in table1: for l2 in table2: if l1[cle] == l2[cle]: fusion = {} for k, v in l1.items(): fusion[k] = v for k, v in l2.items(): if k != cle: fusion[k] = v resultat.append(fusion) return resultat4. Clé primaire et clé étrangère
Section intitulée « 4. Clé primaire et clé étrangère »4.1 Clé primaire
Section intitulée « 4.1 Clé primaire »Une clé primaire est un attribut (ou un ensemble d'attributs) qui identifie de manière unique chaque ligne d'une table. Aucune autre ligne ne peut avoir la même valeur.
Dans la table classes, "classe" est la clé primaire : chaque classe n'apparait qu'une seule fois.
4.2 Clé étrangère
Section intitulée « 4.2 Clé étrangère »Une clé étrangère est un attribut d'une table qui fait référence à la clé primaire d'une autre table.
Dans la table eleves, "classe" est une clé étrangère : elle fait référence à la clé primaire de la table classes.
Table eleves Table classes+---------+---------+------+ +---------+------------+-------+| nom | classe | note | | classe | prof | salle |+---------+---------+------+ +---------+------------+-------+| Dupont | 1NSI-A ------>| | 1NSI-A | M. Duval | 204 || Martin | 1NSI-A ------>| | 1NSI-B | Mme Leroux | 108 || Durand | 1NSI-B ------>| +---------+------------+-------+| Petit | 1NSI-A ------>|+---------+---------+------+4.3 Intérêt
Section intitulée « 4.3 Intérêt »- Pas de redondance : les informations de chaque classe ne sont stockées qu'une seule fois.
- Cohérence : si le prof principal change, on ne modifie qu'une seule ligne dans
classes(et non toutes les lignes deeleves). - Organisation : les données sont séparées par thème logique.
5. Exemple complet : combiner trois tables
Section intitulée « 5. Exemple complet : combiner trois tables »On peut enchaîner les jointures pour fusionner plus de deux tables :
eleves = [ {"id_eleve": 1, "nom": "Dupont", "id_classe": 101}, {"id_eleve": 2, "nom": "Martin", "id_classe": 101}, {"id_eleve": 3, "nom": "Durand", "id_classe": 102}]
classes = [ {"id_classe": 101, "nom_classe": "1NSI-A", "id_prof": 201}, {"id_classe": 102, "nom_classe": "1NSI-B", "id_prof": 202}]
professeurs = [ {"id_prof": 201, "nom_prof": "M. Duval"}, {"id_prof": 202, "nom_prof": "Mme Leroux"}]
# Étape 1 : fusionner élèves et classesetape1 = jointure(eleves, classes, "id_classe")
# Étape 2 : fusionner le résultat avec les professeursresultat = jointure(etape1, professeurs, "id_prof")
for e in resultat: print(f"{e['nom']} - {e['nom_classe']} - {e['nom_prof']}")# Dupont - 1NSI-A - M. Duval# Martin - 1NSI-A - M. Duval# Durand - 1NSI-B - Mme Leroux6. Résumé
Section intitulée « 6. Résumé »| Concept | Détail |
|---|---|
| Redondance | Répétition inutile d'informations dans une table |
| Jointure | Fusion de deux tables sur un attribut commun |
| Clé primaire | Attribut identifiant de manière unique chaque ligne |
| Clé étrangère | Attribut faisant référence à la clé primaire d'une autre table |
| Algorithme | Double boucle : pour chaque ligne de T1, chercher la correspondance dans T2 |
| Sans correspondance | Les lignes sans correspondance sont exclues du résultat |
© 2026 Corentin Dupont - LyCode
Créé avec Astro Starlight