Normalisation
Why normalise?
Imagine storing every club booking in one table, with the coach repeated on every row: each booking of the Chess club would carry "Mr Ng" again and again.
That repetition causes problems. If Mr Ng leaves, you must update many rows; miss one and the data becomes inconsistent. Normalisation organises tables to remove this kind of redundancy.
Pourquoi normaliser ?
Imaginez stocker chaque réservation de club dans une seule table, avec l'entraîneur répété sur chaque ligne : chaque réservation du club d'échecs porterait à nouveau « Mr Ng ».
Cette répétition pose des problèmes. Si Mr Ng quitte, vous devez mettre à jour de nombreuses lignes ; en manquer une et les données deviennent incohérentes. La normalisation organise les tables pour éliminer ce genre de redondance.
The normal forms
You normalise in steps:
- 1NF — every cell holds a single value (no lists or repeating groups), and the table has a primary key.
- 2NF — already 1NF, and no non-key column depends on only part of a composite key.
- 3NF — already 2NF, and no non-key column depends on another non-key column (no transitive dependency).
In the one-table version, coach depends on the club, not on the booking — a transitive dependency, so it is not in 3NF.
Les formes normales
Vous normalisez par étapes :
- 1NF — chaque cellule contient une seule valeur (pas de listes ou de groupes répétés), et la table a une clé primaire.
- 2NF — déjà 1NF, et aucune colonne non-clé ne dépend uniquement d'une partie d'une clé composite.
- 3NF — déjà 2NF, et aucune colonne non-clé ne dépend d'autre colonne non-clé (pas de dépendance transitive).
Dans la version à une table, coach dépend de la club, pas de la réservation — une dépendance transitive, c'est pourquoi ce n'est pas en 3NF.
The normalised design
We split the data into two tables (the ones loaded here):
club(club_id, name, coach)— each club and its coach, stored once.booking(booking_id, student, club_id)— each booking, linked by the foreign keyclub_id.
Now a coach is stored once. A JOIN puts the information back together whenever you need it — write that join below.
La conception normalisée
Nous avons divisé les données en deux tables (celles chargées ici) :
club(club_id, name, coach)— chaque club et son entraîneur, stocké une seule fois.booking(booking_id, student, club_id)— chaque réservation, liée par la clé étrangèreclub_id.
Maintenant, un entraîneur est stocké une seule fois. Un JOIN rassemble les informations à nouveau chaque fois que vous en avez besoin — écrivez ce joint ci-dessous.
Common mistakes
- Split repeating groups into their own table instead of many similar columns.
- Each table should describe one kind of thing.
Erreurs courantes
- Divisez les groupes répétitifs dans leur propre table au lieu de nombreuses colonnes similaires.
- Chaque table devrait décrire un seul type de chose.
Reassemble the data: list each booking's student next to their club's coach, by joining booking to · à club on club_id, ordered by booking.booking_id. · Réassemblez les données : répertoriez la student de chaque réservation à côté de la coach de leur club, en jointant booking à club sur club_id, trié par booking.booking_id.
Click Run to see the output here. · Cliquez sur Exécuter pour voir le résultat ici.
The split tables still answer questions together. Count how many bookings each club has: join booking to · à club, show club.name and · et COUNT(*) AS bookings, group by the club, and order by club.name. · Les tables divisées répondent toujours aux questions ensemble. Comptez combien de réservations chaque club a : jointez booking à club, affichez club.name et COUNT(*) AS bookings, group by le club, et order by club.name.
Click Run to see the output here. · Cliquez sur Exécuter pour voir le résultat ici.