Aller au contenu principal

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 :

idCommandeclientvilleproduitprixqte
1AliceParisClavier402
2AliceParisSouris151
3BobLyonClavier401

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.

Vérification rapideon peut se reprendre

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.

1NF, la règle

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 :

idCommandeproduit
1Clavier
1Souris
1Écran
2Clavier

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.

idCommandeclientproduits
11DurandClavier, Souris, Écran
22LeroyClavier
33MoreauSouris, É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 tient parfaitement, et la table n'est pourtant pas exploitable : c'est la 1NF qui manque, pas une dépendance.
À manipuler
Cliquer sur idCommande → client, produits : trois groupes d'une seule ligne, la dépendance est vérifiée. Lire ensuite, sous le tableau, la forme normale atteinte : aucune, la 1NF n'est pas satisfaite.

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 :

idClientproduit1produit2produit3
1ClavierSouris
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.

idCommandeidProduitnomProduitprixCataloguequantite
110P01Clavier402
311P01Clavier403
210P02Souris151

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.

Deux dépendances vérifiées, mais une seule porte sur la clé entière. L'autre est partielle, et c'est elle qui fabrique la redondance.
À manipuler
Sur idProduit → nomProduit, prixCatalogue, le groupe de P01 réunit les lignes 1 et 3 : Clavier 40 écrit deux fois. Cliquer sur idCommande, idProduit → quantite : trois groupes d'une seule ligne, rien n'est recopié. Cliquer enfin sur Appliquer la décomposition : Clavier 40 n'est plus écrit qu'une fois.

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.

2NF, la règle

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é.

Le prix payé n'est pas le prix du catalogue

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.

idEmployenomidServicenomServicebatiment
11GirardS1EtudesB
22LemoineS2SupportA
33BarbierS1EtudesB

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.

La seconde dépendance a pour gauche un attribut qui n'est pas la clé. Le regroupement par idService montre la ligne « Etudes, B » écrite deux fois pour un seul service.
À manipuler
Cliquer sur idService → nomService, batiment : S1 réunit Girard et Barbier, Etudes B écrit deux fois, et la figure dit cette fois que la dépendance viole la 3NF, pas la 2NF : la clé n'a qu'un attribut, aucune gauche ne peut en être une partie.

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à.

3NF, la règle

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.

idTechnicienemailnomidAgence
1T1renaud@maintenance.frRenaudA1
2T2picard@maintenance.frPicardA2
3T3lebon@maintenance.frLebonA1

Les lignes sont regroupées par idTechnicien (3 groupes). Dans chacun, email, nom, idAgence garde la même valeur : la dépendance tient.

L'adresse électronique détermine le nom, et la table reste en 3NF : l'adresse est une clé candidate, elle ne recopie rien.
À manipuler
Cliquer sur email → nom : trois groupes d'une seule ligne, et la figure lit la gauche comme une clé de la table, « la situation normale ». Comparer avec idService → nomService, batiment dans la figure des employés : là, le groupe de S1 comptait deux lignes et recopiait « Etudes, B ».

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'Affectation faut-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.

etudiantmatiereenseignant
1MartinBases de donneesDurand
2DialloBases de donneesDurand
3MartinStatistiquesAubert
4DialloStatistiquesLeclerc

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.

Deux clés candidates, et chaque attribut appartient à l'une ou à l'autre : la 2NF et la 3NF n'ont rien à reprocher. La seconde dépendance a pourtant pour gauche un attribut qui n'est pas une clé.

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.

À manipuler
Cliquer sur enseignant → matiere : Durand réunit deux lignes, « Bases de donnees » écrit deux fois, et la forme normale atteinte s'affiche sous le tableau : 3NF, mais pas la BCNF. Cliquer sur Appliquer la décomposition, puis lire sous les deux tables la dépendance que la décomposition perd.

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.

Vérification rapideon peut se reprendre

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.

idAlternantidEntreprisenomAlternantnomEntreprisevilleidTuteurposteTuteur
1E1GarnierKerlanRennesT1214
2E1BenaliKerlanRennesT2305
2E2BenaliOudonVannesT1214
3E2RouxOudonVannesT1214

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.

Vérification rapideon peut se reprendre

Le corrigé ne sort posteTuteur qu'à l'étape de la 3NF, pas dès celle de la 2NF. Pourquoi ?

Le corrigé
  1. Écrire les dépendances. Les règles en donnent quatre : idAlternant → nomAlternant, idEntreprise → nomEntreprise, ville, (idAlternant, idEntreprise) → idTuteur et idTuteur → 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.
  2. Sortir les dépendances partielles (2NF). La clé compte deux colonnes. nomAlternant dépend du seul idAlternant : il sort dans Alternant(idAlternant, nomAlternant). nomEntreprise et ville dépendent de la seule idEntreprise : ils sortent dans Entreprise(idEntreprise, nomEntreprise, ville). Il reste Suivi(idAlternant, idEntreprise, idTuteur, posteTuteur).
  3. Sortir les dépendances transitives (3NF). Dans Suivi, posteTuteur dépend de idTuteur, qui n'est pas la clé : il sort dans Tuteur(idTuteur, posteTuteur), et idTuteur reste dans Suivi comme clé étrangère.
  4. 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.
  5. Écrire les tables, puis vérifier sur les données.
Modèle logique de données
Alternant
idAlternant
nomAlternant
Entreprise
idEntreprise
nomEntreprise
ville
Tuteur
idTuteur
posteTuteur
Suivi
idAlternant→ Alternant
idEntreprise→ Entreprise
idTuteur→ Tuteur

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.

idElevedateLeconnomEleveidMoniteurnomMoniteuragence
12026-03-02MorelM1VidalNord
12026-03-09MorelM2CaronSud
22026-03-02FabreM1VidalNord
32026-03-04HenryM1VidalNord

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é
  1. Écrire les dépendances. Les règles en donnent trois : idEleve → nomEleve, (idEleve, dateLecon) → idMoniteur et idMoniteur → nomMoniteur, agence.
  2. Sortir les dépendances partielles (2NF). La clé compte deux colonnes. nomEleve dépend du seul idEleve, une partie de la clé : il sort dans Eleve(idEleve, nomEleve). idMoniteur dépend du couple entier et reste ; nomMoniteur et agence aussi, à cette étape, puisqu'ils dépendent du couple par l'intermédiaire du moniteur, et non d'une partie de la clé.
  3. Sortir les dépendances transitives (3NF). Dans ce qui reste, nomMoniteur et agence dépendent de idMoniteur, qui n'est pas la clé : ils sortent dans Moniteur(idMoniteur, nomMoniteur, agence), et idMoniteur reste dans Lecon comme clé étrangère.
  4. Écrire les tables. Trois tables, chacune avec une seule sorte de dépendance, qui a la clé pour gauche.
Modèle logique de données
Eleve
idEleve
nomEleve
Moniteur
idMoniteur
nomMoniteur
agence
Lecon
idEleve→ Eleve
dateLecon
idMoniteur→ Moniteur

clé primaire clé étrangère, avec la table visée

  1. 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 : Lecon retrouve le nom de l'élève et celui du moniteur par une jointure sur idEleve et sur idMoniteur.

Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?

Dans la bibliothèque d'exercices