Normalisation : remettre de l'ordre dans les données

Imaginez un tableau universitaire dans lequel une cellule répertorie tous les cours d’un étudiant séparés par des virgules, et où le téléphone et l’adresse sont mélangés. Si quelqu'un change de nom de famille ou déménage, vous devrez trouver et réparer cette chaîne à de nombreux endroits. La normalisation est la division délibérée des données en tables et relations pour supprimer les duplications, éviter les contradictions et simplifier la maintenance de la base de données.

Pourquoi s'embêter ? Trois classes d'anomalies
Ouvrir une carte - qu'est-ce qui casse sans normalisation
Le chemin de normalisation : 1NF → 2NF → 3NF
Cliquez sur les étapes – ordre de décomposition
1NF
Atomicité - supprime les listes à l'intérieur des cellules
2NF
Clé entière – supprime les dépendances partielles
3NF
Uniquement à partir de la clé – supprimez les dépendances transitives
Première forme normale (1NF)

La règle 1NF est simple : chaque cellule contient une valeur indivisible d'un domaine. Pas de « listes séparées par des virgules » dans un champ – utilisez des lignes séparées ou un tableau séparé pour cela.

Correctif 1NF – version « avant »
sql
1
-- Bad: 1NF violation — multiple phones in one cell
2
CREATE TABLE students_bad (
3
    id          SERIAL PRIMARY KEY,
4
    full_name   TEXT NOT NULL,
5
    phones      TEXT  -- '+7999..., +7911...'
6
);
Correctif 1NF – version « après »
sql
1
-- Good: 1NF — one phone per row
2
CREATE TABLE students (
3
    id        SERIAL PRIMARY KEY,
4
    full_name TEXT NOT NULL
5
);
6
CREATE TABLE student_phones (
7
    id         SERIAL PRIMARY KEY,
8
    student_id INT NOT NULL REFERENCES students(id),
9
    phone      TEXT NOT NULL
10
);
Deuxième forme normale (2NF)

2NF est important lorsque la clé primaire est composite. Chaque attribut non clé doit dépendre de la clé entière et non d’une partie de celle-ci. Si la clé est le couple « étudiant + cours », alors la durée du cours dépend uniquement du cours : la stocker sur la ligne d'inscription revient à copier la même valeur et à risquer une dérive.

Correctif 2NF – version « avant »
sql
1
-- Bad: partial dependency on a composite key
2
CREATE TABLE enrollments_bad (
3
    student_id   INT NOT NULL,
4
    course_id    INT NOT NULL,
5
    enrolled_at  DATE NOT NULL,
6
    course_duration_hours INT NOT NULL, -- duplicate per student
7
    PRIMARY KEY (student_id, course_id)
8
);
Correctif 2NF – version « après »
sql
1
-- Good: duration stored once, in the course catalog
2
CREATE TABLE courses (
3
    id          SERIAL PRIMARY KEY,
4
    title       TEXT NOT NULL,
5
    duration_hours INT NOT NULL
6
);
7
CREATE TABLE enrollments (
8
    student_id  INT NOT NULL,
9
    course_id   INT NOT NULL REFERENCES courses(id),
10
    enrolled_at DATE NOT NULL,
11
    PRIMARY KEY (student_id, course_id)
12
);
Troisième forme normale (3NF)

3NF interdit les dépendances transitives : une colonne non clé ne doit pas dépendre d'une autre colonne non clé. Si un étudiant a « cityid » et que « cityname » est dupliqué à côté, le nom de la ville dépend de l'identifiant de la ville, et non de la clé primaire de l'étudiant. Le nom doit résider dans une table de recherche distincte.

Correctif 3NF – version « avant »
sql
1
-- Bad: city_name depends transitively on city_id, not on student id
2
CREATE TABLE students_bad_city (
3
    id         SERIAL PRIMARY KEY,
4
    full_name  TEXT NOT NULL,
5
    city_id    INT NOT NULL,
6
    city_name  TEXT NOT NULL  -- duplicate lookup
7
);
Correctif 3NF – version « après »
sql
1
-- Good: city lookup; student has only city_id
2
CREATE TABLE cities (
3
    id        SERIAL PRIMARY KEY,
4
    name      TEXT NOT NULL
5
);
6
CREATE TABLE students (
7
    id        SERIAL PRIMARY KEY,
8
    full_name TEXT NOT NULL,
9
    city_id   INT NOT NULL REFERENCES cities(id)
10
);
Aide-mémoire

1NF • 2NF • 3NF en un coup d'œil

La normalisation n’est ni un dogme ni un fractionnement sans fin : elle supprime la redondance jusqu’à ce que les anomalies d’insertion, de suppression et de mise à jour cessent de menacer les données. Pour enseigner les schémas OLTP, 3NF est souvent un point de départ raisonnable.
1NF : valeur indivisible dans chaque cellule
2NF : les attributs non-clés dépendent de la clé primaire entière
3NF : les attributs non-clés dépendent uniquement de la clé, pas les uns des autres
Moins de copies redondantes — moins de dérive et une maintenance plus facile