Normaliser une base
Ce que ce chapitre apporte 4 points
- Nommer l'anomalie de mise à jour, d'insertion ou de suppression que produit une table qui recopie une information
- Identifier la forme normale qui manque à une table, d'après ses dépendances
- Normaliser une table jusqu'à la troisième forme normale
- Reconnaître une table en troisième forme normale qui n'est pas en forme de Boyce-Codd
Le service des relations entreprises de l'école suit ses alternants dans un tableur : une ligne par alternant et par entreprise d'accueil, avec le nom de l'alternant, le nom et la ville de l'entreprise, le tuteur de l'école qui suit l'alternant chez elle et le numéro de poste de ce tuteur. La scolarité veut l'importer dans sa base. Aucune valeur n'y est fausse, et pourtant le poste d'un tuteur qui suit trois alternants est écrit trois fois, une entreprise qui n'accueille personne cette année n'a aucune ligne où exister, et corriger une ville oblige à retrouver chacune de ses lignes. Quelles colonnes recopient une information, en combien de tables découper ce tableur, et à quoi reconnaître qu'on peut s'arrêter de découper ? Ce chapitre s'appuie sur les dépendances fonctionnelles du chapitre sur les systèmes d'information, et sur les tables, les clés et les clés étrangères du chapitre sur le modèle relationnel.
Pourquoi normaliser ?
Une table range toutes les informations d'une commande sur une seule ligne :
| idCommande | client | ville | produit | prix | qte |
|---|---|---|---|---|---|
| 1 | Alice | Paris | Clavier | 40 | 2 |
| 2 | Alice | Paris | Souris | 15 | 1 |
| 3 | Bob | Lyon | Clavier | 40 | 1 |
Problèmes :
- Si Alice déménage, il faut modifier toutes ses commandes → anomalie de mise à jour
- Si on supprime la commande 2, on perd le prix de la Souris, qui n'apparaît dans aucune autre commande → anomalie de suppression (et supprimer la commande 3 ferait disparaître Bob et sa ville)
- On ne peut pas ajouter un produit sans créer une commande → anomalie d'insertion
La normalisation élimine ces problèmes en décomposant les tables selon des règles précises.
Dépendances fonctionnelles
Le chapitre sur les systèmes d'information les a posées : A → B quand chaque valeur de A ne va qu'avec une seule valeur de B, et le sens compte. Les formes normales ne sont que des questions posées à ces dépendances.
1.Une table Cours(idCours, intitule, enseignant, bureau) écrit le bureau de chaque enseignant à côté de chacun de ses cours. Une enseignante arrive sans cours cette année : son bureau n'a aucune ligne où s'écrire. Quelle anomalie est-ce ?
2.Dans la table des commandes de la section « Pourquoi normaliser ? », laquelle de ces dépendances les trois lignes vérifient-elles ?
Première Forme Normale (1NF)
Une table de commandes range dans une colonne produits la valeur Clavier, Souris, Écran. Rien n'interdit de l'écrire, et la table s'affiche parfaitement. Compter les ventes de souris devient pourtant impossible : le contenu de la cellule est une chaîne de caractères, pas trois produits. C'est cette situation que la première forme normale interdit.
Chaque cellule contient une et une seule valeur atomique. Pas de listes, pas de groupes répétés dans une colonne.
Mise en 1NF, la commande 1 prend une ligne par produit :
| idCommande | produit |
|---|---|
| 1 | Clavier |
| 1 | Souris |
| 1 | Écran |
| 2 | Clavier |
La figure suivante fait le diagnostic sur les données elles-mêmes.
Cliquer sur une dépendance pour regrouper le tableau par sa partie gauche.
Vérifiée sur les 3 lignes : la gauche est exactement une clé de la table : c'est la situation normale.
| idCommande | client | produits | |
|---|---|---|---|
| 1 | 1 | Durand | Clavier, Souris, Écran |
| 2 | 2 | Leroy | Clavier |
| 3 | 3 | Moreau | Souris, Écran |
Les lignes sont regroupées par idCommande (3 groupes). Dans chacun, client, produits garde la même valeur : la dépendance tient.
Forme normale atteinte : aucune, la 1NF n'est pas satisfaite
- 1NFla colonne produits contient une liste (« Clavier, Souris, Écran »). Une cellule doit porter une seule valeur.
La dépendance idCommande → client, produits y est vérifiée sans réserve : une table peut satisfaire toutes ses dépendances et rester inutilisable.
Défaut voisin, des colonnes répétées :
| idClient | produit1 | produit2 | produit3 |
|---|---|---|---|
| 1 | Clavier | Souris | |
| 2 | Écran |
Chaque cellule y est atomique, et la 1NF au sens strict n'y voit rien à redire. Le défaut est pourtant le même : un quatrième produit oblige à modifier la structure, et chercher un produit, à regarder trois colonnes.
Deuxième Forme Normale (2NF)
Le prix catalogue du clavier change. Dans la table Vente ci-dessous, de clé (idCommande, idProduit), ce prix est recopié sur chaque ligne de commande qui contient un clavier : en oublier une en le modifiant suffit pour que la base donne deux prix catalogue au même produit.
Cliquer sur une dépendance pour regrouper le tableau par sa partie gauche.
Vérifiée sur les 3 lignes : la gauche est une PARTIE d'une clé seulement, ce qui viole la 2NF.
| idCommande | idProduit | nomProduit | prixCatalogue | quantite | |
|---|---|---|---|---|---|
| 1 | 10 | P01 | Clavier | 40 | 2 |
| 3 | 11 | P01 | Clavier | 40 | 3 |
| 2 | 10 | P02 | Souris | 15 | 1 |
Les lignes sont regroupées par idProduit (2 groupes). Dans chacun, nomProduit, prixCatalogue garde la même valeur : la dépendance tient.
Forme normale atteinte : 1NF
- 2NFnomProduit, prixCatalogue ne dépend que de idProduit, c'est-à-dire d'une partie de la clé (idCommande, idProduit). La valeur est donc réécrite à chaque ligne qui partage cette partie.
La décomposition qui règle le problème :
- Vente (idCommande, idProduit, quantite)
- Produit (idProduit, nomProduit, prixCatalogue)
Les attributs soulignés forment la clé primaire de chaque table.
nomProduit et prixCatalogue dépendent seulement de idProduit, pas du couple (idCommande, idProduit) : les deux dépendances de la table n'ont pas la même partie gauche, ce qui s'écrit avant la flèche, et c'est exactement le symptôme. Une dépendance à une partie de la clé s'appelle une dépendance partielle, et la deuxième forme normale l'interdit.
La table est en 1NF et chaque attribut non-clé dépend de la totalité de la clé primaire, pas d'une partie seulement (pas de dépendance partielle). En toute rigueur, la règle vaut pour chaque clé possible de la table, pas seulement pour celle qu'on a choisie comme clé primaire.
La 2NF ne peut être violée que par une table dont la clé est composite : une clé d'une seule colonne n'a pas de partie dont un attribut pourrait dépendre.
Après (2NF), les attributs sont séparés selon leur dépendance : Produit(idProduit, nomProduit, prixCatalogue) et Vente(idCommande, idProduit, quantite). Le prix catalogue du clavier ne s'écrit plus qu'à un seul endroit, donc il ne peut plus se contredire. En échange, connaître le nom du produit d'une commande demande désormais de recoller les deux tables sur idProduit, ce qu'on appelle une jointure (chapitre sur l'algèbre relationnelle) : c'est le prix de la normalisation, et il est presque toujours bon marché.
Une commande déjà passée ne doit pas changer de montant quand le catalogue change : sa facture est un document comptable. Le prix auquel le clavier a été vendu dans la commande 10 dépend donc du couple (idCommande, idProduit), pas du seul produit, et il reste dans la ligne de commande, à côté de la quantité : LigneCommande(idCommande, idProduit, quantite, prixVente). prixCatalogue dans Produit et prixVente dans la ligne ne sont pas une redondance : ce sont deux faits différents, qui ont le droit de diverger.
Troisième Forme Normale (3NF)
Le service Etudes déménage du bâtiment B au bâtiment C. Dans la table d'employés ci-dessous, qui porte à la fois idService, nomService et batiment, ce déménagement coûte autant de modifications qu'il y a d'employés aux Etudes, et un service sans employé n'a nulle part où exister. La figure met les deux dépendances de la table côte à côte, et c'est leur partie gauche qu'il faut comparer.
Cliquer sur une dépendance pour regrouper le tableau par sa partie gauche.
Vérifiée sur les 3 lignes : la gauche est exactement une clé de la table : c'est la situation normale.
| idEmploye | nom | idService | nomService | batiment | |
|---|---|---|---|---|---|
| 1 | 1 | Girard | S1 | Etudes | B |
| 2 | 2 | Lemoine | S2 | Support | A |
| 3 | 3 | Barbier | S1 | Etudes | B |
Les lignes sont regroupées par idEmploye (3 groupes). Dans chacun, nom, idService garde la même valeur : la dépendance tient.
Forme normale atteinte : 2NF
- 3NFnomService, batiment dépend de idService, qui n'est pas la clé. La chaîne idEmploye → idService → nomService, batiment est une dépendance transitive.
La décomposition qui règle le problème :
- Employe (idEmploye, nom, idService)
- Service (idService, nomService, batiment)
Les attributs soulignés forment la clé primaire de chaque table.
nomService et batiment ne dépendent pas de idEmploye, mais de idService, qui n'est lui-même pas la clé. La chaîne est idEmploye → idService → nomService : c'est une dépendance transitive, qui passe par une colonne intermédiaire. La troisième forme normale vise ce défaut-là.
La table est en 2NF et aucun attribut non-clé ne dépend d'un autre attribut non-clé (pas de dépendance transitive).
« Non-clé » désigne un attribut qui n'appartient à aucune des clés possibles de la table, qu'on appelle ses clés candidates.
Après (3NF), Employe(idEmploye, nom, idService) désigne Service(idService, nomService, batiment). Le déménagement ne touche plus qu'une ligne, un service vide s'enregistre sans difficulté, et chaque table ne porte plus qu'une seule dépendance, qui a la clé pour gauche.
Reste un cas que la règle, lue trop vite, condamnerait. Une table des techniciens porte l'adresse électronique de chacun, qui n'appartient qu'à lui : email → nom est vraie, et email n'est pas la clé primaire. Ce n'est pas une dépendance transitive : l'adresse est une clé candidate, elle ne se répète jamais, et le nom n'est écrit qu'une fois.
Cliquer sur une dépendance pour regrouper le tableau par sa partie gauche.
Vérifiée sur les 3 lignes : la gauche est exactement une clé de la table : c'est la situation normale.
| idTechnicien | nom | idAgence | ||
|---|---|---|---|---|
| 1 | T1 | renaud@maintenance.fr | Renaud | A1 |
| 2 | T2 | picard@maintenance.fr | Picard | A2 |
| 3 | T3 | lebon@maintenance.fr | Lebon | A1 |
Les lignes sont regroupées par idTechnicien (3 groupes). Dans chacun, email, nom, idAgence garde la même valeur : la dépendance tient.
Ce que la décomposition fait des copies
- 1.
La table
Affectation(idProjet, idEmploye, nomEmploye, idService, nomService, heures)a pour clé(idProjet, idEmploye): un employé n'appartient qu'à un service, et ses heures se comptent projet par projet. En combien de tables la décomposition en 3NF la découpe-t-elle ? - 2.
Un service compte 8 employés, chacun affecté à 12 projets. Le service change de nom : combien de lignes d'
Affectationfaut-il réécrire avant la décomposition ? - 3.
Et combien de lignes faut-il réécrire, toutes tables comprises, après la décomposition en 3NF ?
Au-delà de la 3NF : la forme de Boyce-Codd
Une table peut passer les trois tests et garder une redondance. Dans une école, chaque enseignant n'enseigne qu'une matière, et chaque étudiant n'a qu'un enseignant par matière.
Cliquer sur une dépendance pour regrouper le tableau par sa partie gauche.
Vérifiée sur les 4 lignes : la gauche est exactement une clé de la table : c'est la situation normale.
| etudiant | matiere | enseignant | |
|---|---|---|---|
| 1 | Martin | Bases de donnees | Durand |
| 2 | Diallo | Bases de donnees | Durand |
| 3 | Martin | Statistiques | Aubert |
| 4 | Diallo | Statistiques | Leclerc |
Les lignes sont regroupées par etudiant, matiere (4 groupes). Dans chacun, enseignant garde la même valeur : la dépendance tient.
Forme normale atteinte : 3NF, mais pas la BCNF
- BCNFmatiere dépend de enseignant, qui n'est pas une clé : la valeur est réécrite à chaque ligne qui partage enseignant. matiere faisant partie d'une clé, ni la 2NF ni la 3NF ne l'interdisent : la table est en 3NF, mais pas en BCNF.
La décomposition qui règle le problème :
- Encadrement (etudiant, enseignant)
- Enseignant (enseignant, matiere)
Les attributs soulignés forment la clé primaire de chaque table.
Cette décomposition perd la dépendance etudiant, matiere → enseignant : aucune des tables n'en porte tous les attributs, et la vérifier demande une jointure.
Chacun de ses trois attributs appartient à une clé candidate : la 2NF et la 3NF, qui ne parlent que des attributs non-clés, la laissent passer. La matière de Durand y est pourtant écrite deux fois, une par étudiant qu'il encadre, et un enseignant qui n'encadre encore personne n'a aucune ligne où dire ce qu'il enseigne. La forme normale de Boyce-Codd (BCNF) le reproche : la partie gauche de chaque dépendance doit être une clé de la table. enseignant → matiere ne l'est pas.
La décomposition qu'elle propose sépare Enseignant (enseignant, matiere), où la matière ne s'écrit plus qu'une fois par enseignant, et Encadrement (etudiant, enseignant). Elle a un prix, que la figure écrit sous la décomposition : la règle « un étudiant n'a qu'un enseignant par matière », etudiant, matiere → enseignant, ne se lit plus dans aucune des deux tables, et la vérifier demande une jointure. Rien n'empêcherait plus d'inscrire Martin auprès d'Aubert et de Leclerc, tous deux en statistiques. C'est pourquoi la plupart des modèles s'arrêtent à la 3NF, et ne vont en BCNF que lorsque la règle perdue peut se vérifier autrement.
1.Une colonne produits contient « Clavier, Souris, Écran ». Quelle forme normale est violée ?
2.Dans une table de clé (idCommande, idProduit), la colonne prixCatalogue ne dépend que de idProduit. Quelle forme normale est violée ?
3.Une table Employe(idEmploye, nom, idService, nomService) a pour clé idEmploye, et nomService dépend de idService. Quelle forme normale manque ?
4.Dans un club, chaque moniteur n'enseigne qu'un sport, et chaque adhérent n'a qu'un moniteur par sport. La table Suivi(adherent, sport, moniteur) a deux clés candidates, (adherent, sport) et (adherent, moniteur). Où en est-elle ?
Une base peut aussi recopier des valeurs exprès : une base qui sert surtout à lire de très gros volumes dénormalise, pour répondre sans recoller dix tables, comme le modèle en étoile du chapitre sur l'entrepôt de données. Recopier se décide alors en connaissance de cause, avec un moyen de tenir la copie à jour, jamais par oubli.
Mettre en pratique
Le tableur des alternants, de l'ouverture : quelles colonnes recopient une information, en combien de tables le découper, et à quoi reconnaître qu'on peut s'arrêter ?
Le tableur devient la table Alternance(idAlternant, idEntreprise, nomAlternant, nomEntreprise, ville, idTuteur, posteTuteur), de clé (idAlternant, idEntreprise) : un alternant peut changer d'entreprise en cours de formation, et dans chaque entreprise un seul tuteur de l'école le suit. Un tuteur suit des alternants dans plusieurs entreprises, et garde le même numéro de poste.
| idAlternant | idEntreprise | nomAlternant | nomEntreprise | ville | idTuteur | posteTuteur |
|---|---|---|---|---|---|---|
| 1 | E1 | Garnier | Kerlan | Rennes | T1 | 214 |
| 2 | E1 | Benali | Kerlan | Rennes | T2 | 305 |
| 2 | E2 | Benali | Oudon | Vannes | T1 | 214 |
| 3 | E2 | Roux | Oudon | Vannes | T1 | 214 |
Par où commencer ? Écrire d'abord, pour chaque colonne hors de la clé, ce qui la détermine d'après les règles : toute la clé, une partie de la clé, ou une autre colonne.
Le corrigé ne sort posteTuteur qu'à l'étape de la 3NF, pas dès celle de la 2NF. Pourquoi ?
Le corrigé
- Écrire les dépendances. Les règles en donnent quatre :
idAlternant → nomAlternant,idEntreprise → nomEntreprise, ville,(idAlternant, idEntreprise) → idTuteuretidTuteur → posteTuteur. Les colonnes qui se recopient sont celles dont la partie gauche n'est pas le couple entier : le nom de l'alternant, le nom et la ville de l'entreprise, le poste du tuteur. - Sortir les dépendances partielles (2NF). La clé compte deux colonnes.
nomAlternantdépend du seulidAlternant: il sort dansAlternant(idAlternant, nomAlternant).nomEntrepriseetvilledépendent de la seuleidEntreprise: ils sortent dansEntreprise(idEntreprise, nomEntreprise, ville). Il resteSuivi(idAlternant, idEntreprise, idTuteur, posteTuteur). - Sortir les dépendances transitives (3NF). Dans
Suivi,posteTuteurdépend deidTuteur, qui n'est pas la clé : il sort dansTuteur(idTuteur, posteTuteur), etidTuteurreste dansSuivicomme clé étrangère. - Vérifier qu'on peut s'arrêter. Dans chacune des quatre tables, la seule dépendance qui reste a pour partie gauche la clé de la table : aucune ne recopie plus rien, et chacune est même en forme de Boyce-Codd. C'est le signe d'arrêt : une table de plus ne retirerait aucune copie, elle n'ajouterait qu'une jointure.
- Écrire les tables, puis vérifier sur les données.
clé primaire clé étrangère, avec la table visée
Avant la décomposition, « Kerlan, Rennes » et « Oudon, Vannes » sont écrits deux fois, et le poste 214 trois fois. Après, chacun ne l'est qu'une fois, dans sa table, et une entreprise qui n'accueille personne cette année garde sa ligne dans Entreprise. Rien n'est perdu : Suivi retrouve chaque nom par une jointure sur ses trois clés étrangères.
Une auto-école range tout son planning dans une seule table. Jusqu'où la décomposer, et en quelles tables ?
L'auto-école enregistre ses leçons dans Lecon(idEleve, dateLecon, nomEleve, idMoniteur, nomMoniteur, agence), de clé (idEleve, dateLecon) : un élève prend au plus une leçon par jour, donnée par un seul moniteur, et chaque moniteur est rattaché à une agence. Quand un moniteur change d'agence, la secrétaire corrige toutes ses leçons, une à une.
| idEleve | dateLecon | nomEleve | idMoniteur | nomMoniteur | agence |
|---|---|---|---|---|---|
| 1 | 2026-03-02 | Morel | M1 | Vidal | Nord |
| 1 | 2026-03-09 | Morel | M2 | Caron | Sud |
| 2 | 2026-03-02 | Fabre | M1 | Vidal | Nord |
| 3 | 2026-03-04 | Henry | M1 | Vidal | Nord |
Par où commencer ? Écrire d'abord, pour chaque colonne hors de la clé, ce qui la détermine d'après les règles : toute la clé, une partie de la clé, ou une autre colonne.
Le corrigé
- Écrire les dépendances. Les règles en donnent trois :
idEleve → nomEleve,(idEleve, dateLecon) → idMoniteuretidMoniteur → nomMoniteur, agence. - Sortir les dépendances partielles (2NF). La clé compte deux colonnes.
nomElevedépend du seulidEleve, une partie de la clé : il sort dansEleve(idEleve, nomEleve).idMoniteurdépend du couple entier et reste ;nomMoniteuretagenceaussi, à cette étape, puisqu'ils dépendent du couple par l'intermédiaire du moniteur, et non d'une partie de la clé. - Sortir les dépendances transitives (3NF). Dans ce qui reste,
nomMoniteuretagencedépendent deidMoniteur, qui n'est pas la clé : ils sortent dansMoniteur(idMoniteur, nomMoniteur, agence), etidMoniteurreste dansLeconcomme clé étrangère. - Écrire les tables. Trois tables, chacune avec une seule sorte de dépendance, qui a la clé pour gauche.
clé primaire clé étrangère, avec la table visée
- Vérifier sur les données. Avant la décomposition, « Vidal, Nord » est écrit trois fois et « Morel » deux fois. Après, chaque nom n'est écrit qu'une fois, dans sa table, et le changement d'agence de Vidal ne touche plus qu'une ligne de
Moniteur. Rien n'est perdu :Leconretrouve le nom de l'élève et celui du moniteur par une jointure suridEleveet suridMoniteur.
Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?
Dans la bibliothèque d'exercices
Dire quelle forme normale manque à une table, sortir les dépendances partielles puis transitives, et écrire les tables qui en sortent.
- Quelle forme normale manqueNiveau 1
- Décomposer jusqu'à la troisième forme normaleNiveau 2
- Normaliser, puis écrire les tablesNiveau 2
- Les consultations d'une clinique, jusqu'à la 3NFNiveau 1
- Le prélèvement mal découpéNiveau 2
- Un atelier par spécialitéNiveau 3