La normalisation de base de données offre un lot de principes faciles à appliquer. Ils aideront le développeur à structurer sa base de données et améliorer les performances MySql.
Normaliser une base de données revient à organiser les données de manière plus efficace, logique, grâce à des règles normales, des principes normaux (qui donnent une norme). Pour plus d’efficacité, le processus de normalisation résultera en la construction de tables et de relations entre ces tables. La normalisation de base de données offre :
- une structure optimisée qui ne gâche pas l’espace disque (la même donnée ne devrait pas être trouvée dans plus d’une table pour des raisons évidentes : la mise à jour de plusieurs tables pour la même donnée est absurde)
- des dépendances logiques (implique l’enregistrement des données pertinentes à l’intérieur de ou en relation à la bonne table)
Les Formes Normales
Je me concentrerai ici sur les 3 premières règles, que les spécialistes appellent formes normales. Ces règles devraient ajouter suffisamment d’efficacité à votre base de données. Gardez en mémoire qu’il est parfois préférable de ne pas appliquer une règle (et donc d’interrompre la normalisation) pour des raisons pratiques. En effet, la normalisation consiste en l’ajout de tables de relation (qui créent un lien entre d’autres tables), par exemple, qui nécessiteront un changement par le développeur de ses requêtes MySql.
Les formes normales doivent être appliquées dans l’ordre : une normalisation avancée ne peut se produire que dans le cas où les règles précédentes de normalisation ont déjà été appliquées.
Pour une meilleure compréhension, je prends l’exemple d’une base de données discographique qui enregistre les albums d’artistes célèbres.
Créer la base de données à froid sans expérience de normalisation résulterait en la création d’une seule table :
records_table :
record_ID : 1 (defini comme Primary_KEY)
artist : Fleetwood Mac est un groupe américano-britannique formé en 1967…
record_title : The pious bird of good omen
record_style : Blues, Rock, Pop
record_label : blue horizon
record_release : 1969
Avec cette table simpliste, vous comprendrez aisément que :
- une requête SELECT ne peut obtenir de l’information à propos d’un artiste sans connaître un record_ID
- une requête UPDATE qui veut modifier la biographie d’un artiste devra le faire dans chaque ligne de la table associée à l’artiste en question
- une requête DELETE effacera l’information concernant l’album ainsi que l’information concernant l’artiste
Ces limitations produiront des anomalies comme la corruption de données, des problèmes de ressource MySql (à cause des sous-requêtes LIKE),… Il est donc temps de normaliser cette base et nous le ferons grâce à la théorie relationnelle.
La Théorie relationnelle
1NF => La première Forme Normale : la forme atomique
Chaque champ de table devrait avoir une valeur atomique, c’est-à-dire une seule valeur dans la colonne de votre table. Dans l’exemple ci-dessus, les champs ‘record_artist’ et ‘record_style’ contiennent plus qu’une seule valeur. L’application de la 1NF résultera en la création de 2 tables supplémentaires :
records_table :
record_ID : 1 (defini comme Primary_KEY)
record_title : The pious bird of good omen
record_release : 1969
and
artists_table :
artist_ID : 1 (defini as Primary Key)
artist_name : Fleetwood Mac
artist_bio : Fleetwood Mac est un groupe américano-britannique formé en 1967
et
styles_table (avec 3 entrées) :
style_ID : 1 (defini comme Primary Key)
style_name : blues
style_ID : 2
style_name : pop
style_ID : 3
style_name : rock
Il est maintenant facile d’ajoute run artiste sans devoir ajouter un album pour cet artiste, vous pouvez effacer un album sans pour autant effacer l’information concernant l’artiste,…
Les données sont maintenant séparées dans des tables différentes. Il faut maintenant créer les liens, relations entre ces tables. Les relations de base de données peuvent être du type suivant :
1 à 1 : un élément de la table A correspond à un élément de la table B et cet élément de la table B correspond à un seul élément de la table A
1 à N : un enregistrement de la records_table n’est associé qu’à un seul label mais ce label peut être associé à un nombre illimité d’enregistrements de la table records_table. Dans ce cas, nous ajouterons une clef étrangère à la table records table contenant le label_ID
N à N : un enregistrement de la records_table peut être associé à plus d’un artiste et un artiste de la artists_table peut être associé à plus d’un enregistrement de la records_table. Dans ce cas, nous créerons une table supplémentaire appelée records_artists_table, une table de relation qui liera la records_table avec la artists_table
Ajoutons une clef étrangère à la records_table pour la gestion des label_ID:
records_table : relation 1 à N
record_ID : 1 (defini comme Primary_KEY)
record_title : The pious bird of good omen
record_release : 1969
label_ID : 1
avec la table des labels associée :
labels_table :
label_ID : 1 (défini comme PRIMARY KEY)
label_name : Blue horizon
et créons la nouvelle table :
records_artists_table : relation N à N
record_ID : 1 (clef primaire définie sur les 2 champs)
artist_ID : 1 (clef primaire définie sur les 2 champs)
Nous pourrions définir le même genre de relation entre la table records_table et les styles de musique :
records_styles_table : relation N à N
record_ID : 1 (clef primaire définie sur les 2 champs)
style_ID : 1 (clef primaire définie sur les 2 champs)
2NF => la seconde Forme Normale : les relations aux clefs
Cette Forme Normale s’assure que les colonnes qui ne sont pas définies comme clef dépendent strictement de la clef primaire. Ainsi, dans le cas d’une clef composite (une ligne de la table est identifiée grâce au record_ID et au author_ID), toutes les colonnes non définies comme clef doivent dépendre des 2 champs, etpas seulement à l’une d’entre elles. Imaginez la structure suivante :
records_reviews table :
record_ID : 1 (defined as primary key with the following field)
author_ID : 1 (defined as primary key with the previous field)
review : This compilation album is one of my favourites…
author_website : http://www.domain.com
Dans l’exemple ci-dessus, le champ ‘author_website’ ne dépend pas strictement de la clef composite record_ID-author_ID. Il dépend uniquement de l’author_ID. Appliquer la seconde forme normale revient à déplacer le champ author_website field vers la table authors_table.
3NF => la troisième Forme Normale
labels_table :label_ID : 1 (primary key)label_name : Blue Horizonlabel_zip : 1770label_city : Sherbornlabel_state : MA
zip_table :zip_ID : 1770 (primary key)zip_city : Sherbornzip_state : MA
labels_table :label_ID : 1 (primary key)label_name : Blue Horizonzip_ID : 1770
states_table :state_ID : 1 (primary key)state_name : MA
SELECT * FROM labels as A INNER JOIN zip as B ON B.zip_ID=A.zip_ID INNER JOIN states as C ON C.state_ID=B.state_ID WHERE A.label_ID=’1′ LIMIT 1;
Webliographie :