Aller au contenu

Merise : normalisation

La normalisation supprime les redondances d’un schéma relationnel pour éviter les anomalies de mise à jour. Un MCD bien construit donne en général un MLD déjà normalisé ; la normalisation sert à vérifier et à corriger.

Exemple de table mal conçue :

num_commande date client email_client article prix
1 2026-01-10 Alice alice@exemple.com Clavier 49
1 2026-01-10 Alice alice@exemple.com Souris 25
2 2026-01-12 Alice alice@exemple.com Clavier 49
Anomalie Exemple
Redondance L’e-mail d’Alice est répété à chaque ligne
Mise à jour Changer l’e-mail oblige à modifier plusieurs lignes ; en oublier une crée une incohérence
Insertion Impossible d’enregistrer un nouveau client avant sa première commande
Suppression Supprimer la seule commande d’un client efface aussi les informations du client

Chaque colonne contient une valeur atomique (non décomposable), et il n’y a ni groupe répétitif ni liste dans une cellule.

Violation Exemple
Liste dans une cellule telephones = '0601020304, 0102030405'
Colonnes répétées article1, article2, article3
Valeur composite adresse = '12 rue X, 69001 Lyon' (si on a besoin du code postal ou de la ville séparément)

Correction : une table liée (TELEPHONE), une table associative (LIGNE_COMMANDE), des colonnes distinctes (rue, code_postal, ville).

La table est en 1FN et toute colonne non clé dépend de la clé entière (pas d’une partie seulement). Elle ne concerne que les clés composées.

Table LIGNE_COMMANDE (num_commande, reference, quantite, libelle_article, prix) avec la clé (num_commande, reference) :

  • quantite dépend de la clé entière (commande et article) : correct.
  • libelle_article et prix ne dépendent que de reference (une partie de la clé) : violation de la 2FN.

Correction : déplacer libelle et prix dans la table ARTICLE (reference, libelle, prix).

La table est en 2FN et aucune colonne non clé ne dépend d’une autre colonne non clé (pas de dépendance transitive).

Table COMMANDE (num_commande, date, num_client, nom_client, email_client) :

  • num_client dépend de num_commande : correct.
  • nom_client et email_client dépendent de num_client (qui n’est pas la clé de COMMANDE) : dépendance transitive.

Correction : déplacer nom_client, email_client dans CLIENT (num_client, nom, email).

Formule mémorisable : « chaque colonne dépend de la clé, de toute la clé, et de rien d’autre que la clé ».

Plus stricte que la 3FN : pour toute dépendance X → Y, X doit être une clé candidate (ou contenir une clé). Un écart avec la 3FN n’apparaît que dans des cas particuliers (clés candidates composées qui se chevauchent).

Exemple : INSCRIPTION (etudiant, cours, enseignant) avec les règles « un étudiant suit plusieurs cours », « un enseignant n’enseigne qu’un cours » : enseignant → cours alors que enseignant n’est pas une clé. Correction : séparer ENSEIGNEMENT (enseignant, cours) et INSCRIPTION (etudiant, enseignant).

En pratique, viser la 3FN (souvent BCNF d’office).

Départ (tout dans une table) :

COMMANDE_PLATE (num_commande, date, num_client, nom_client, email_client, reference, libelle, prix, quantite)
  1. 1FN : valeurs atomiques ; la clé est (num_commande, reference) (une ligne par article d’une commande).
  2. 2FN : date, num_client, nom_client, email_client ne dépendent que de num_commande ; libelle et prix ne dépendent que de reference. On sépare :
    • COMMANDE (num_commande, date, num_client, nom_client, email_client)
    • ARTICLE (reference, libelle, prix)
    • LIGNE_COMMANDE (num_commande, reference, quantite)
  3. 3FN : dans COMMANDE, nom_client et email_client dépendent de num_client : on sépare :
    • CLIENT (num_client, nom, email)
    • COMMANDE (num_commande, date, num_client)

Résultat : les quatre tables du MLD du fil rouge (Du MCD au modèle logique). Le MCD bien fait donnait directement ce résultat.

Pour chaque table :

  1. Quelle est la clé ? Est-elle minimale ?
  2. Chaque colonne non clé dépend-elle de la clé entière ? (2FN)
  3. Existe-t-il une colonne qui se déduit d’une autre colonne non clé ? (3FN)
  4. Peut-on changer une information en un seul endroit ?
  5. Peut-on insérer et supprimer sans effets indésirables ?

Normaliser n’est pas toujours optimal : la lecture exige davantage de jointures. On dénormalise volontairement, après mesure, pour :

Cas Technique Risque
Lecture très fréquente d’un total Colonne total_commande mise à jour (déclencheur, application) Incohérence si la mise à jour échoue
Historique à conserver Copier prix_unitaire dans la ligne de commande C’est un choix métier : le prix payé, distinct du prix actuel
Rapports lourds Table de synthèse recalculée périodiquement Données légèrement en retard
Performances de lecture Vues matérialisées (PostgreSQL) À rafraîchir
Bases de documents Données imbriquées dans le document Mise à jour des copies

Règles : normaliser d’abord, mesurer ensuite (voir PostgreSQL : index et performances), dénormaliser à un endroit précis et documenter le choix et la façon dont la donnée est maintenue.

Dans une base de documents (MongoDB, CouchDB), on imbrique souvent les données lues ensemble (lignes de commande dans le document de commande). Le raisonnement est différent : on modélise selon les accès plutôt que selon la normalisation. Un modèle relationnel bien normalisé reste le bon point de départ quand les données sont fortement liées.

Symptôme Piste
La même information à plusieurs endroits 2FN ou 3FN non respectée : la déplacer dans sa propre table
Une colonne qui se calcule La supprimer, ou la déclarer volontairement dénormalisée et documentée
Valeurs séparées par des virgules dans une colonne 1FN : table liée
Trop de jointures, requêtes lentes Mesurer ; index d’abord, dénormalisation ensuite
Données incohérentes après une mise à jour Redondance non maintenue : la supprimer ou automatiser sa mise à jour
Clé primaire composée de nombreuses colonnes Clé de substitution (id) + contrainte d’unicité

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune.