Leçon 2 / 20

Normaliser les tables sans perdre d’information

25 min SQL — modélisation, index et optimisation Gratuit

Objectif : Repérer les anomalies de conception et décomposer les tables jusqu’à la troisième forme normale.

Une table qui rassemble les adhérents, les œuvres et les emprunts paraît pratique au départ. Dès qu’une œuvre possède plusieurs exemplaires ou qu’un adhérent effectue plusieurs emprunts, les mêmes informations se répètent et deviennent difficiles à maintenir. Vous allez séparer les faits qui n’ont pas la même portée, sans perdre la possibilité de les retrouver ensemble.

La leçon précédente a établi les entités et les relations de la médiathèque ; vous vous appuyez sur ce modèle plutôt que de les redéfinir. Normaliser consiste à organiser les informations pour que chaque fait soit enregistré à l’endroit approprié, avec le moins de redondance possible. La décomposition doit cependant conserver les associations utiles : les données séparées devront pouvoir être rapprochées.

Partir des anomalies

Imaginez une table suivi_mediatheque dont chaque ligne mélange l’identité d’un adhérent, le titre d’une œuvre, l’identifiant d’un exemplaire et les dates d’un emprunt. Le nom de l’adhérent et le titre de l’œuvre y sont répétés à chaque emprunt correspondant. Cette répétition crée trois anomalies : une correction du titre doit être reportée sur plusieurs lignes ; une œuvre sans emprunt est difficile à enregistrer ; supprimer le dernier emprunt d’une œuvre peut aussi faire disparaître la seule ligne qui décrivait cette œuvre.

Première forme normale : une valeur par information

Une table est en première forme normale quand chaque cellule contient une valeur élémentaire pour le domaine considéré, et non une liste ou un groupe de valeurs. Une colonne exemplaires qui contiendrait « 101, 102, 103 » empêche de traiter chaque exemplaire séparément : il devient notamment difficile de retrouver celui qui est actuellement emprunté. Représentez les exemplaires par des lignes distinctes, rattachées à l’œuvre concernée, plutôt que par une liste inscrite dans une cellule.

La première forme normale ne suffit pas à éviter les répétitions. Si chaque ligne décrit un emprunt, les renseignements propres à l’œuvre ou à l’adhérent réapparaissent à chaque nouvel emprunt. Il faut donc examiner quelles informations dépendent de l’emprunt lui-même et lesquelles décrivent une autre entité.

Deuxième forme normale : séparer les faits partiels

La deuxième forme normale concerne les relations dont l’identifiant repose sur plusieurs valeurs combinées. Elle exige que chaque information descriptive dépende de l’identifiant complet, et non d’une seule de ses composantes. Par exemple, dans une association entre un exemplaire et un emprunt, la date de retour prévue décrit l’emprunt ; le titre décrit l’œuvre. Si le titre est stocké dans cette association et ne dépend que de l’œuvre, il faut le placer avec les informations de l’œuvre.

Dans le modèle de la médiathèque, cette séparation conduit à distinguer les informations des adhérents, des œuvres, des exemplaires, des emprunts et des retards. Une ligne d’emprunt décrit le prêt effectué par un adhérent sur un exemplaire à une date donnée ; elle ne doit pas devenir le lieu de stockage du nom complet de l’adhérent ou du titre de l’œuvre. Ces informations seront rapprochées par les relations du modèle, dont les contraintes seront étudiées dans une leçon ultérieure.

Troisième forme normale : éviter les dépendances indirectes

La troisième forme normale exige que les informations descriptives d’une relation dépendent de son identifiant, et pas d’une autre information descriptive de cette même relation. Supposons qu’une ligne d’emprunt contienne adherent_id, nom_adherent et date_emprunt. Le nom dépend de l’adhérent, pas directement de l’emprunt : le conserver ici crée une dépendance indirecte et impose de le répéter à chaque prêt de cette personne.

Déplacez alors nom_adherent dans la relation adherents et conservez dans emprunts la référence à l’adhérent avec les faits propres au prêt. Appliquez le même raisonnement au titre : il décrit l’œuvre et non chaque exemplaire ni chaque emprunt. Le résultat est plus cohérent : une correction du nom ou du titre s’effectue à un seul endroit.

Vérifier qu’une décomposition conserve les données

Séparer des colonnes n’est pas suffisant : il faut pouvoir reconstruire les associations observées auparavant. L’exemple autonome ci-dessous présente deux emprunts et deux œuvres, puis recompose les informations par jointure. Il utilise des relations temporaires définies dans la requête et n’ajoute encore aucune définition au fichier de schéma du projet.

SQL
WITH
    oeuvres (oeuvre_id, titre) AS (
        SELECT 10, 'Le fleuve'
        UNION ALL
        SELECT 20, 'La carte'
    ),
    emprunts (emprunt_id, oeuvre_id, date_emprunt) AS (
        SELECT 501, 10, '2025-03-01'
        UNION ALL
        SELECT 502, 10, '2025-03-08'
    )
SELECT
    emprunts.emprunt_id,
    oeuvres.titre,
    emprunts.date_emprunt
FROM emprunts
INNER JOIN oeuvres
    ON oeuvres.oeuvre_id = emprunts.oeuvre_id
ORDER BY emprunts.emprunt_id;
Résultat attendu
emprunt_id | titre      | date_emprunt
501        | Le fleuve  | 2025-03-01
502        | Le fleuve  | 2025-03-08

Les deux lignes de résultat conservent leurs emprunts et retrouvent le titre correspondant, même si celui-ci n’est enregistré qu’une fois dans la relation des œuvres. Pour valider une décomposition, comparez les associations avant et après la séparation sur des cas représentatifs : plusieurs emprunts pour une œuvre, plusieurs exemplaires pour une œuvre et des entités sans emprunt. Une jointure mal définie peut multiplier ou écarter des lignes ; la forme normale ne dispense donc pas de vérifier le résultat.

À retenir

  • Évitez les listes de valeurs dans une cellule : chaque exemplaire ou emprunt doit pouvoir être traité séparément.
  • En deuxième forme normale, chaque information descriptive dépend de l’identifiant complet de la relation.
  • En troisième forme normale, une information descriptive ne dépend pas indirectement d’une autre information descriptive.
  • Une décomposition doit supprimer les répétitions tout en permettant de retrouver les associations par jointure.
  • Les dépendances déjà étudiées dans la leçon sur les règles métier aident à décider où ranger chaque fait.

Dans la leçon suivante, vous traduirez ce modèle normalisé en tables SQL et protégerez sa cohérence avec des contraintes.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.