Tout ranger dans une seule table, comme dans un tableur, semble la solution la plus simple. On la teste sur les données d'une école et on mesure les dégâts : redondance, anomalies et fautes invisibles.
L'école veut connaître la classe de chaque élève, avec le local de cette classe et le professeur titulaire. Le réflexe naturel consiste à tout ranger dans un seul tableau. Dans cet article, tu testes cette solution sur de vraies données et tu regardes précisément ce qui casse.
💡 Base de travail
Télécharge
bulletin-plat.dbdans la carte « Téléchargements » de la sidebar, puis ouvre-le avec DB Browser for SQLite. Ce fichier suffit pour suivre tout l'article.
À la fin de cet article, tu seras capable de :
SELECT DISTINCT.La demande du secrétariat tient en une phrase :
« Ajoutez la classe de chaque élève, avec son local et le professeur titulaire. »
La solution la plus rapide consiste à tout mettre dans un seul tableau, comme on le ferait dans un tableur. C'est ce que contient le fichier bulletin-plat.db. Ouvre l'onglet Parcourir les données et choisis la table bulletin_plat :
eleve_nom | eleve_prenom | classe | classe_local | titulaire_nom | titulaire_email
----------+--------------+--------+--------------+--------------------+----------------------
Adam | Lucas | 4TTR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
Bastin | Emma | 4TTR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
Charlier | Noah | 4TTR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
Delvaux | Léa | 4TRR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
Englebert | Hugo | 4TTR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
Fontaine | Chloé | 5TTR | A21 | Dubois Sophie | s.dubois@ecole.be
Gérard | Nathan | 5TTR | A21 | Dubois Sophie | s.dubois@ecole.be
Hubert | Manon | 5TTR | A21 | Dubois Sophie | s.dubois@ecoles.be
Istas | Louis | 5TTR | A21 | Dubois Sophie | s.dubois@ecole.be
Jacques | Camille | 6TTR | A23 | Vermeulen Marc | m.vermeulen@ecole.be
Kevers | Arthur | 6TTR | A23 | Vermeulen Marc | m.vermeulen@ecole.be
Toutes les informations demandées sont là. Et pourtant, deux erreurs se sont déjà glissées dans ces onze lignes. Avant de lire la suite, essaie de les trouver à l'œil. Note ce que tu trouves : on vérifiera plus bas.
Compte combien de fois l'adresse l.lambrechts@ecole.be est écrite : cinq fois. Et le local B14 ? Cinq fois aussi. Pourtant, Ludovic Lambrechts n'a qu'une seule adresse, et la classe 4TTR n'a qu'un seul local.
📖 Nouvelle notion : la redondance
Il y a redondance quand un même fait est écrit à plusieurs endroits d'une base. Ici, « le local de la 4TTR est le B14 » est écrit cinq fois, une fois par élève de la classe.
En anglais : 🇬🇧 redundancy.
On pourrait croire que la redondance fait seulement perdre de la place. C'est faux : elle rend la base fragile. Chaque fois qu'on ajoute, modifie ou supprime des données, on risque de créer une contradiction.
📖 Nouvelle notion : l'anomalie
Une anomalie est un problème qui apparaît quand on ajoute, modifie ou supprime des données dans une table qui mélange plusieurs choses. La base ne signale rien : elle accepte l'opération, mais le résultat est incomplet ou contradictoire.
En anglais : 🇬🇧 anomaly.
On distingue trois anomalies, une par type d'opération. Un quatrième problème, plus sournois, les accompagne.
Ludovic Lambrechts change d'adresse e-mail. Dans ce tableau, il faut modifier cinq lignes. Avec vingt-cinq élèves par classe, il en faudrait vingt-cinq.
Si tu en oublies une, la base contient deux adresses différentes pour la même personne. Plus rien ne dit laquelle est la bonne.
🧠 L'anomalie de modification
Un seul changement doit être répété sur plusieurs lignes. Si on en oublie une, la base se contredit elle-même, sans aucun message d'erreur.
L'école ouvre une classe de 3TTR pour la rentrée prochaine, dans le local B10, avec Anne Leroy comme titulaire. Aucun élève n'y est encore inscrit.
Où enregistres-tu cette classe ? Nulle part. Dans ce tableau, chaque ligne décrit un élève : une classe n'existe que si un élève y est inscrit. Tu pourrais créer une ligne en laissant vides les colonnes de l'élève, mais tu obtiendrais un élève sans nom, qui fausserait tous tes comptages.
🧠 L'anomalie d'insertion
On ne peut pas enregistrer une information sans en inventer une autre qui n'a rien à voir avec elle.
Camille Jacques et Arthur Kevers quittent l'école. Ce sont les deux seuls élèves de 6TTR : tu supprimes leurs deux lignes.
Du même coup, tu effaces la classe 6TTR, son local A23 et le fait que Marc Vermeulen en est le titulaire. Personne n'a demandé ça.
🧠 L'anomalie de suppression
Effacer une information en efface une autre au passage.
Revenons aux deux erreurs du début. Lire les lignes une à une est lent, et l'œil se trompe vite. Il est plus sûr de demander à la base la liste des valeurs différentes d'une colonne.
ℹ️ Rappel :
SELECT DISTINCT
DISTINCTveut dire distinct, différent.SELECT DISTINCT colonne FROM tableaffiche chaque valeur de la colonne une seule fois, sans répétition.
Commence par la colonne classe :
SELECT DISTINCT classe FROM bulletin_plat ORDER BY classe;
classe
------
4TRR
4TTR
5TTR
6TTR
L'école compte trois classes, mais la base en affiche quatre. 4TRR est une faute de frappe : c'est la ligne de Léa Delvaux. Recommence avec les adresses des titulaires :
SELECT DISTINCT titulaire_email FROM bulletin_plat ORDER BY titulaire_email;
titulaire_email
---------------------
l.lambrechts@ecole.be
m.vermeulen@ecole.be
s.dubois@ecole.be
s.dubois@ecoles.be
Trois titulaires, mais quatre adresses : Sophie Dubois en a deux. La ligne de Manon Hubert contient ecoles au lieu de ecole.
💡 Un réflexe de contrôle
Sur une colonne qui ne devrait contenir que quelques valeurs (des classes, des locaux, des adresses de professeurs), lance un
SELECT DISTINCT. Toute valeur en trop est suspecte.
Ces fautes ont des conséquences bien réelles. Demande la liste des élèves de 4TTR :
SELECT eleve_prenom, eleve_nom FROM bulletin_plat WHERE classe = '4TTR';
eleve_prenom | eleve_nom
-------------+----------
Lucas | Adam
Emma | Bastin
Noah | Charlier
Hugo | Englebert
La base répond sans erreur, mais Léa Delvaux n'apparaît pas. Si le secrétariat imprime les bulletins de la 4TTR à partir de cette liste, Léa n'aura pas le sien.
🧠 Les incohérences silencieuses
Aucune des deux fautes n'a provoqué de message d'erreur. La base les a acceptées, parce que rien ne lui dit que la classe
4TRRn'existe pas. La redondance ne crée pas les fautes de frappe : elle leur laisse la place de se glisser, puis elle les cache.
Pourquoi tous ces problèmes ? Regarde de près la ligne de Lucas Adam :
Adam | Lucas | 4TTR | B14 | Lambrechts Ludovic | l.lambrechts@ecole.be
└─ élève ──┘ └ classe ┘ └────────────── professeur ──────────────┘
Cette ligne raconte trois choses différentes : un élève, une classe et un professeur. Dans une base de données, chacune de ces choses est une entité : une chose dont on veut garder la trace, décrite par ses attributs (un nom, un local, une adresse…).
Or chaque entité vit sa propre vie. Un élève change de classe, une classe change de titulaire, un professeur change d'adresse. Quand on les mélange dans une même ligne, chaque changement de l'une oblige à toucher aux données des autres.
🧠 La règle qui découle de tout ça
Une entité = une table. Un fait est écrit à un seul endroit.
S'il faut écrire l'adresse de Ludovic Lambrechts cinq fois, c'est qu'il manque une table
professeur. S'il faut écrireB14cinq fois, c'est qu'il manque une tableclasse.
Découper le tableau en trois tables règle la redondance. Mais une nouvelle question apparaît aussitôt : si les élèves sont dans une table et les classes dans une autre, comment la base sait-elle que Lucas Adam est en 4TTR ?
Tous les exercices portent sur bulletin-plat.db. Ne corrige pas les fautes : le but est de mesurer les dégâts. L'exercice 3 modifie la base : fais-le sur une copie du fichier, ou télécharge-le à nouveau ensuite.
SELECT DISTINCT sur la colonne classe_local. Combien de valeurs obtiens-tu ? Ce résultat révèle-t-il la faute 4TRR ?titulaire_nom. Pourquoi cette colonne ne révèle-t-elle pas la faute dans l'adresse de Sophie Dubois ?s.dubois@ecole.be. Combien en trouves-tu ?ℹ️ Rappel :
UPDATE
UPDATEveut dire mettre à jour etSETveut dire régler.UPDATE table SET colonne = nouvelle_valeur WHERE condition;modifie les lignes où la condition est vraie ; sansWHERE, toutes les lignes sont modifiées.
Sophie Dubois change d'adresse e-mail. Sa nouvelle adresse est s.dubois-renard@ecole.be.
bulletin_plat ?UPDATE qui remplace l'adresse s.dubois@ecole.be par la nouvelle, puis exécute-la. DB Browser affiche le nombre de lignes modifiées : note-le.SELECT DISTINCT sur titulaire_email. Que constates-tu ? Explique pourquoi.Pour chaque demande, écris ce que tu tenterais, puis explique précisément ce qui bloque et à quelle anomalie cela correspond.
Sans écrire de SQL, sur papier :
SELECT DISTINCT colonne liste les valeurs différentes d'une colonne : c'est un outil simple pour repérer les fautes.Découper les données en plusieurs tables supprime la redondance, mais il faut alors relier chaque élève à sa classe. C'est l'objet de l'article Relier deux entités.