cours
Normalisation en SQL (1NF - 5NF) : Guide du débutant
Dans cet article, nous allons explorer les concepts de base que vous devez connaître sur la normalisation, son importance et les différentes techniques impliquées. Cet article s'adresse, sans s'y limiter, à ceux qui cherchent à percer dans le secteur des données et à devenir des data scientists ou des data engineers.
Qu'est-ce que la normalisation en SQL ?
La normalisation, dans ce contexte, est le processus d'organisation des données au sein d'une base de données(base de données relationnelle) afin d'éliminer les anomalies de données, telles que la redondance.
En termes plus simples, il s'agit de décomposer un grand tableau complexe en tableaux plus petits et plus simples tout en conservant les relations entre les données.
La normalisation est couramment utilisée lorsqu'il s'agit de traiter de grands ensembles de données.
Examinons brièvement quelques scénarios dans lesquels la normalisation est souvent utilisée.
Intégrité des données
Imaginez une base de données contenant des informations sur les clients. Sans normalisation, si un client change d'âge, nous devrions le mettre à jour à plusieurs endroits, ce qui augmenterait le risque d'incohérences. En normalisant les données, nous pouvons avoir des tableaux distincts liés par un identifiant unique qui garantira l'exactitude et la cohérence des données.
Recherche d'efficacité
Prenons l'exemple d'une base de données complexe comportant plusieurs tableaux liés entre eux et stockant des informations redondantes. Dans ce cas, les requêtes impliquant des jointures deviennent plus compliquées et plus gourmandes en ressources. La normalisation contribuera à simplifier l'interrogation en décomposant les données en tableaux plus petits, chaque tableau ne contenant que les informations pertinentes, ce qui réduira la nécessité d'effectuer des jointures complexes.
Optimisation du stockage
L'un des principaux problèmes des données redondantes est qu'elles occupent un espace de stockage inutile. Par exemple, si nous stockons les mêmes détails sur les produits dans chaque enregistrement de commande, cela entraîne une duplication. La normalisation vous permet d'éliminer les redondances en répartissant les données dans des tableaux distincts.
Pourquoi la normalisation est-elle importante dans SQL ?
La normalisation joue un rôle crucial dans la conception des bases de données. Voici plusieurs raisons pour lesquelles il est essentiel :
- Réduit la redondance : On parle de redondance lorsque la même information est stockée plusieurs fois. Un bon moyen d'éviter cela est de diviser les données en tableaux plus petits.
- Améliore les performances des requêtes : Vous pouvez exécuter plus rapidement des requêtes sur des tableaux plus petits ayant fait l'objet d'une normalisation.
- Minimise les anomalies de mise à jour : Avec les tableaux normalisés, vous pouvez facilement mettre à jour les données sans affecter les autres enregistrements.
- Améliore l'intégrité des données : Il garantit la cohérence et l'exactitude des données.
Pourquoi la normalisation est-elle nécessaire ?
Si un tableau n'est pas correctement normalisé et présente une redondance de données, il occupera non seulement un espace de stockage supplémentaire, mais rendra également difficiles la manipulation et la mise à jour de la base de données.
Plusieurs facteurs justifient le besoin de normalisation, de la redondance des données (comme nous l'avons vu plus haut) à la difficulté de gérer les relations. Entrons dans le vif du sujet :
- Anomalies d'insertion, de suppression et de mise à jour : Toute modification d'un tableau peut entraîner des erreurs ou des incohérences dans d'autres tableaux si elle n'est pas traitée avec soin. Ces modifications peuvent consister à ajouter de nouvelles données à une base de données, à mettre à jour les données ou à supprimer des enregistrements, ce qui peut entraîner une perte involontaire de données.
- Difficulté à gérer les relations : Il devient plus difficile de maintenir des relations complexes dans une structure non normalisée.
- Les dépendances parti elles et les dépendances transitives sont d'autres facteurs qui rendent la normalisation nécessaire. Les dépendances partielles peuvent entraîner une redondance des données et des anomalies de mise à jour, tandis que les dépendances transitives peuvent entraîner des anomalies de données. Dans les prochaines sections, nous verrons comment ces dépendances peuvent être traitées pour assurer la normalisation de la base de données.
Différents types de normalisation des bases de données
Jusqu'à présent, nous avons examiné ce qu'est la normalisation en SQL, pourquoi la normalisation en SQL est importante et quelles sont les causes du besoin de normalisation. La normalisation des bases de données se présente sous différentes formes, chacune avec des niveaux croissants d'organisation des données.
Dans cette section, nous aborderons brièvement les différents niveaux de normalisation avant de les approfondir dans la section suivante.
Image par l'auteur
Première forme normale (1NF)
Ce niveau de normalisation garantit que chaque colonne de vos données ne contient que des valeurs atomiques. Dans ce contexte, les valeurs atomiques signifient que chaque entrée d'une colonne est indivisible. C'est comme si l'on disait que chaque cellule d'une feuille de calcul ne devait contenir qu'une seule information. La 1NF garantit l'atomicité des données, chaque cellule de colonne ne contenant qu'une seule valeur et chaque colonne ayant un nom unique.
Deuxième forme normale (2NF)
Élimine les dépendances partielles en veillant à ce que les attributs autres que la clé ne dépendent que de la clé primaire. Cela signifie essentiellement qu'il doit y avoir une relation directe entre chaque colonne et la clé primaire, et non entre les autres colonnes.
Troisième forme normale (3NF)
Supprime les dépendances transitives en veillant à ce que les attributs non clés ne dépendent que de la clé primaire. Ce niveau de normalisation s'appuie sur la norme 2NF.
Forme normale de Boyce-Codd (BCNF)
Il s'agit d'une version plus stricte de la 3NF qui tient compte d'autres anomalies. À ce niveau de normalisation, chaque déterminant est une clé candidate.
Quatrième forme normale (4NF)
Il s'agit d'un niveau de normalisation qui s'appuie sur la BCNF en traitant les dépendances multivaluées.
Cinquième forme normale (5NF)
La 5NF est le niveau de normalisation le plus élevé qui prend en compte les dépendances de jointure. Il est utilisé dans des scénarios spécifiques pour minimiser davantage la redondance en divisant un tableau en tableaux plus petits.
Normalisation des bases de données avec des exemples concrets
Nous avons déjà mis en évidence tous les niveaux de normalisation des données. Examinons chacun d'entre eux de manière plus approfondie à l'aide d'exemples et d'explications.
Normalisation de la première forme normale (1NF)
La méthode 1NF garantit que chaque cellule de la colonne ne contient que des valeurs atomiques. Imaginez une base de données de bibliothèque avec un tableau stockant des informations sur les livres (titre, auteur, genre et borrowed_by). Si le tableau n'est pas normalisé, borrowed_by peut contenir une liste de noms d'emprunteurs séparés par des virgules. Ceci est contraire à la 1NF, puisqu'une seule cellule peut contenir plusieurs valeurs. Le tableau ci-dessous est une bonne représentation d'un tableau qui viole la 1NF, comme décrit précédemment.
title |
auteur |
genre |
emprunté_par |
Tuer l'oiseau moqueur |
Harper Lee |
Fiction |
John Doe, Jane Doe, James Brown |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
Fantaisie |
Emily Garcia, David Lee |
Harry Potter et la pierre du sorcier |
J.K. Rowling |
Fantaisie |
Michael Chen |
La solution ?
Dans 1NF, nous créons un tableau distinct pour les emprunteurs et nous les lions au tableau des livres. Ces tableaux peuvent être liés à l'aide de la clé étrangère du tableau de l'emprunteur ou d'un tableau de liaison distinct. L'approche de la clé étrangère dans la table des emprunteurs consiste à ajouter une colonne de clé étrangère à la table des emprunteurs qui fait référence à la clé primaire de la table des livres. Cela permet d'établir une relation entre les tableaux et d'assurer la cohérence des données.
Vous en trouverez une représentation ci-dessous :
Tableau des livres
book_id (PK) |
title |
auteur |
genre |
1 |
Tuer l'oiseau moqueur |
Harper Lee |
Fiction |
2 |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
Fantaisie |
3 |
Harry Potter et la pierre du sorcier |
J.K. Rowling |
Fantaisie |
Tableau des emprunteurs
borrower_id (PK) |
nom |
book_id (FK) |
1 |
John Doe |
1 |
2 |
Jane Doe |
1 |
3 |
James Brown |
1 |
4 |
Emily Garcia |
2 |
5 |
David Lee |
2 |
6 |
Michael Chen |
3 |
Deuxième forme normale (2NF)
Ce niveau de normalisation, comme nous l'avons déjà décrit, s'appuie sur la 1NF en garantissant qu'il n'y a pas de dépendances partielles sur la clé primaire. En d'autres termes, tous les attributs non clés doivent dépendre de l'ensemble de la clé primaire et pas seulement d'une partie de celle-ci.
D'après la 1NF qui a été mise en œuvre, nous disposons déjà de deux tableaux distincts (vous pouvez consulter la section sur la 1NF).
Supposons maintenant que nous voulions relier ces tableaux pour enregistrer les emprunts. L'approche initiale pourrait consister à ajouter simplement une colonne borrower_id au tableau des tableaux, comme indiqué ci-dessous :
book_id (PK) |
title |
auteur |
genre |
borrower_id (FK) |
1 |
Tuer l'oiseau moqueur |
Harper Lee |
Fiction |
1 |
2 |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
Fantaisie |
NULL |
3 |
Harry Potter et la pierre du sorcier |
J.K. Rowling |
Fantaisie |
6 |
Cela peut sembler une solution, mais elle viole la 2NF simplement parce que l'identifiant de l'emprunteur ne dépend que partiellement de l'identifiant du livre. Un livre peut avoir plusieurs emprunteurs, mais un même borrower_id ne peut être lié qu'à un seul livre dans cette structure. Cela crée une dépendance partielle.
La solution ?
Nous devons établir une relation de plusieurs à plusieurs entre les livres et les emprunteurs afin d'obtenir la fonction 2NF. Cela peut se faire en introduisant un tableau séparé :
Tableau des emprunts comptables
emprunt_id (PK) | book_id (FK) | borrower_id (FK) | borrowed_date |
---|---|---|---|
1 | 1 | 1 | 2024-05-04 |
2 | 2 | 4 | 2024-05-04 |
3 | 3 | 6 | 2024-05-04 |
Ce tableau établit une relation claire entre les tableaux et les emprunteurs. L'identifiant du livre et l'identifiant de l'emprunteur sont des clés étrangères qui renvoient aux clés primaires de leurs tableaux respectifs. Cette approche garantit que borrower_id dépend de l'ensemble de la clé primaire (book_id) du tableau books, ce qui est conforme à la 2NF.
Troisième forme normale (3NF)
La 3NF s'appuie sur la 2NF en éliminant les dépendances transitives. On parle de dépendance transitive lorsqu'un attribut non clé dépend d'un autre attribut non clé, qui dépend à son tour de la clé primaire. Il tire essentiellement son sens de la loi transitive.
D'après la 2NF que nous avons déjà mise en œuvre, il y a trois tableaux dans la base de données de notre bibliothèque :
Tableau des livres
book_id (PK) |
title |
auteur |
genre |
1 |
Tuer l'oiseau moqueur |
Harper Lee |
Fiction |
2 |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
Fantaisie |
3 |
Harry Potter et la pierre du sorcier |
J.K. Rowling |
Fantaisie |
Tableau des emprunteurs
borrower_id (PK) |
nom |
book_id (FK) |
1 |
John Doe |
1 |
2 |
Jane Doe |
1 |
3 |
James Brown |
1 |
4 |
Emily Garcia |
2 |
5 |
David Lee |
2 |
6 |
Michael Chen |
3 |
Tableau des emprunts comptables
emprunt_id (PK) |
book_id (FK) |
borrower_id (FK) |
borrowed_date |
1 |
1 |
1 |
2024-05-04 |
2 |
2 |
4 |
2024-05-04 |
3 |
3 |
6 |
2024-05-04 |
La structure 2NF semble efficace, mais il pourrait y avoir une dépendance cachée. Imaginons que nous ajoutions une colonne due_date au tableau des livres. Cela peut sembler logique à première vue, mais cela va créer une dépendance transitive :
- La colonne due_date dépend de l'borrowing_id (un attribut non clé) du tableau book_borrowings.
- L'borrowing_id dépend à son tour du book_id (la clé primaire) du tableau books.
Cela signifie que due_date s'appuie sur un attribut intermédiaire non clé (borrowing_id) au lieu de dépendre directement de la clé primaire (book_id). Ceci est contraire à la 3NF.
La solution ?
Nous pouvons déplacer la colonne due_date vers le tableau le plus approprié en mettant à jour le tableau book_borrowings pour y inclure les colonnes due_date et returned_date.
Vous trouverez ci-dessous le tableau mis à jour :
emprunt_id (PK) |
book_id (FK) |
borrower_id (FK) |
borrowed_date |
due_date |
1 |
1 |
1 |
2024-05-04 |
2024-05-20 |
2 |
2 |
4 |
2024-05-04 |
2024-05-18 |
3 |
3 |
6 |
2024-05-04 |
2024-05-10 |
En plaçant la colonne due_date dans le tableau book_borrowing, nous avons réussi à éliminer la dépendance transitive.
Cela signifie que la date d'échéance dépend désormais directement de la relation combinée entre l'identifiant du livre et l'identifiant de l'emprunteur. Dans ce contexte, book_id et borrower_id agissent comme une clé étrangère composite qui, ensemble, forment la clé primaire du tableau book_borrowings.
Forme normale de Boyce-Codd (BCNF)
La BCNF est basée sur des dépendances fonctionnelles qui prennent en compte toutes les clés candidates dans une relation.
Les dépendances fonctionnelles (DF) définissent les relations entre les attributs d'une base de données relationnelle. Une DF stipule que la valeur d'une colonne détermine la valeur d'une autre colonne liée. Les DF sont très importants car ils guident le processus de normalisation en identifiant les dépendances et en veillant à ce que les données soient réparties de manière appropriée entre les tableaux.
La BCNF est une version plus stricte de la 3NF. Elle garantit que chaque déterminant (ensemble d'attributs permettant d'identifier une ligne de manière unique) d'un tableau est une clé candidate (ensemble minimal d'attributs permettant d'identifier une ligne de manière unique). L'essentiel est que tous les déterminants puissent servir de clés primaires.
Il garantit que chaque dépendance fonctionnelle (DF) a une superclé comme déterminant. En d'autres termes, si X -> Y (X détermine Y) est valable, X doit être une clé candidate (superclé) de la relation. Veuillez noter que X et Y sont des colonnes dans un tableau de données.
En guise de complément à la 3NF, nous disposons de trois tableaux :
Tableau des livres
book_id (PK) |
title |
auteur |
genre |
1 |
Tuer l'oiseau moqueur |
Harper Lee |
Fiction |
2 |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
Fantaisie |
3 |
Harry Potter et la pierre du sorcier |
J.K. Rowling |
Fantaisie |
Tableau des emprunteurs
borrower_id (PK) |
nom |
book_id (FK) |
1 |
John Doe |
1 |
2 |
Jane Doe |
1 |
3 |
James Brown |
1 |
4 |
Emily Garcia |
2 |
5 |
David Lee |
2 |
6 |
Michael Chen |
3 |
Tableau des emprunts comptables
emprunt_id (PK) |
book_id (FK) |
borrower_id (FK) |
borrowed_date |
due_date |
1 |
1 |
1 |
2024-05-04 |
2024-05-20 |
2 |
2 |
4 |
2024-05-04 |
2024-05-18 |
3 |
3 |
6 |
2024-05-04 |
2024-05-10 |
Bien que la structure 3NF soit bonne, il pourrait y avoir un déterminant caché dans le tableau book_borrowings. En supposant qu'un emprunteur ne puisse pas emprunter deux fois le même livre simultanément, la combinaison de l'identifiant du livre et de l'identifiant de l'emprunteur identifie de manière unique un enregistrement d'emprunt.
Cette structure viole la norme BCNF puisque l'ensemble combiné (book_id et borrower_id) n'est pas la clé primaire du tableau (qui n'est que borrowing_id).
La solution ?
Pour atteindre la BCNF, nous pouvons soit décomposer le tableau book_borrowings en deux tableaux distincts, soit faire de l'ensemble d'attributs combinés la clé primaire.
- Approche 1 (décomposer le tableau) : Dans cette approche, nous décomposerons le tableau book_borrowings en tableaux distincts :
-
- Un tableau avec borrowing_id comme clé primaire, borrowed_date, due_date et returned_date.
- Un autre tableau séparé pour relier les livres et les emprunteurs, avec book_id comme clé étrangère, borrower_id comme clé étrangère, et éventuellement des attributs supplémentaires spécifiques à l'événement d'emprunt.
- Approche 2 (faire du jeu d'attributs combiné la clé primaire) : Nous pouvons envisager de faire de book_id et borrower_id une clé primaire composite pour identifier de manière unique les enregistrements d'emprunt. Le problème de cette approche est qu'elle ne remplit pas sa fonction si un emprunteur peut emprunter le même livre plusieurs fois.
En fin de compte, le choix entre ces options dépend de vos besoins spécifiques en matière de données et de la manière dont vous souhaitez modéliser les relations d'emprunt.
Quatrième forme normale (4NF)
La 4NF traite des dépendances à valeurs multiples. Il existe une dépendance multivaluée lorsqu'un attribut peut avoir plusieurs attributs dépendants et que ces attributs dépendants sont indépendants de la clé primaire. C'est assez complexe, mais nous allons l'explorer plus en profondeur à l'aide d'un exemple.
L'exemple de la bibliothèque que nous avons utilisé tout au long de ces explications n'est pas applicable à ce niveau de normalisation. La 4NF s'applique généralement aux situations dans lesquelles un attribut unique peut avoir plusieurs attributs dépendants qui ne sont pas directement liés à la clé primaire.
Prenons un autre scénario. Imaginez une base de données qui stocke des informations sur les publications. Nous allons considérer un tableau "Publications" avec des tableaux, titre, auteur, année de publication et mots-clés.
publication_id (PK) |
title |
auteur |
publication_year |
keywords |
1 |
Tuer l'oiseau moqueur |
Harper Lee |
1960 |
Passage à l'âge adulte, Juridique |
2 |
Le Seigneur des Anneaux |
J. R. R. Tolkien |
1954 |
Fantaisie, Epique, Aventure |
3 |
Orgueil et préjugés |
Jane Austen |
1813 |
Romance, Commentaire social |
La structure du tableau ci-dessus viole la 4NF car :
- La colonne des mots-clés dépend de la clé primaire publication_id. Cela signifie qu'une publication peut avoir plusieurs mots-clés, et que ces mots-clés sont indépendants de l'identifiant unique de la publication.
La solution ?
Nous pouvons créer un tableau séparé.
Tableau des mots-clés de publication
publication_id (FK) |
keyword |
1 |
Le passage à l'âge adulte |
1 |
Juridique |
2 |
Fantaisie |
2 |
Épique |
2 |
Aventure |
3 |
Romance |
3 |
Commentaire social |
Le tableau nouvellement créé (Publication_mots-clés) établit une relation de plusieurs à plusieurs entre la publication et les mots-clés. Chaque publication peut avoir plusieurs mots-clés liés par l'intermédiaire de l'identifiant de publication, qui est une clé étrangère, et chaque mot-clé peut être associé à plusieurs publications.
Nous avons ainsi réussi à éliminer la dépendance multivaluée et à obtenir la 4NF.
Cinquième forme normale (5NF)
La 5NF est la forme la plus complexe de normalisation qui élimine les dépendances de jointure. Il s'agit d'une situation où les données doivent être jointes à partir de plusieurs tableaux pour répondre à une requête spécifique, même si ces tableaux sont déjà en 4NF.
En d'autres termes, la 5NF garantit qu'aucune information supplémentaire ne peut être obtenue en joignant les tableaux qui n'était pas déjà disponible dans les tableaux séparés.
Les dépendances de jointure sont moins susceptibles de se produire lorsque les tableaux sont déjà normalisés (en 3NF ou 4NF), d'où la difficulté de créer un exemple clair et direct pour la 5NF.
Cependant, examinons ce scénario dans lequel la 5NF peut être pertinente :
Imaginez une base de données universitaire avec des tableaux normalisés pour les "cours" et les "inscriptions".
Tableau des cours
course_id (PK) |
course_name |
département |
101 |
Introduction à la programmation |
Informatique |
202 |
Structures de données et algorithmes |
Informatique |
301 |
Développement Web I |
Informatique |
401 |
Intelligence artificielle |
Informatique |
Tableau des inscriptions
enrollment_id (PK) |
student_id (FK) |
course_id (FK) |
grade |
1 |
12345 |
101 |
A |
2 |
12345 |
202 |
B |
3 |
56789 |
301 |
A- |
4 |
56789 |
401 |
B+ |
En supposant que ces tableaux soient déjà en 3NF ou 4NF, une dépendance de jointure peut exister en fonction de la façon dont les données sont stockées. Par exemple, un cours a une condition préalable stockée dans le tableau "Cours" sous la forme de la colonne "prerequisite_course_id".
Cela peut sembler efficace à première vue. Cependant, considérons une requête qui doit retrouver les cours d'un étudiant et leurs prérequis respectifs. Dans ce scénario, vous devrez joindre les tableaux "Cours" et "Inscriptions", puis éventuellement joindre le tableau "Cours" pour récupérer les informations sur les conditions préalables.
La solution ?
Pour éliminer la dépendance de jointure et atteindre la 5NF, nous pourrions introduire un tableau séparé "Prérequis de cours" :
Tableau des prérequis des cours
course_id (FK) |
prerequisite_course_id (FK) |
202 |
101 |
301 |
NULL |
401 |
202 |
Cette approche sépare les informations sur les prérequis et permet de retrouver efficacement les cours inscrits et leurs prérequis en une seule jointure entre les tableaux "Enrollments" et "Course_prerequisites".
Note : Nous partons du principe qu'un étudiant ne peut avoir qu'un seul prérequis par cours.
La 5NF est un type de normalisation très complexe et rare, de sorte qu'en tant que personne débutant son apprentissage des données, vous risquez de ne pas trouver d'application. Cependant, il s'agit d'une connaissance supplémentaire qui vous permettra d'être prêt à affronter des bases de données complexes.
Développez vos compétences en SQL
Si vous lisez ceci, je vous félicite d'être resté jusqu'à la fin. Nous avons eu beaucoup de plaisir à explorer ce qu'est la normalisation en SQL, pourquoi la normalisation en SQL est importante, quelles sont les causes du besoin de normalisation et quels sont les différents types de normalisation de base de données. Les scénarios utilisés pour expliquer les différents types de normalisation sont destinés à vous permettre de bien comprendre et d'appliquer ces connaissances dans votre parcours d'apprentissage.
La normalisation est une compétence fondamentale pour toute personne débutant sa carrière dans un domaine lié aux données. En comprenant ces principes, vous êtes maintenant prêt à construire des bases de données efficaces et bien organisées.
L'apprentissage est très important dans l'espace de données, et pour vous permettre d'améliorer vos compétences en SQL, nous avons quelques ressources pour vous.
FAQ
Qu'est-ce que la normalisation dans les SGBD ?
La normalisation des bases de données est une technique qui permet de concevoir de manière optimale le schéma d'une base de données relationnelle. Elle consiste à diviser les tableaux en sous-tableaux plus petits et à stocker des pointeurs vers les données plutôt que de les répliquer.
Pourquoi la normalisation est-elle importante ?
La normalisation permet d'éviter la redondance des données, d'améliorer l'intégrité des données et de simplifier la manipulation des données au sein d'une base de données.
Dois-je normaliser ma base de données en 5NF ?
Pas nécessairement. La normalisation 3NF ou 4NF est souvent suffisante pour la plupart des bases de données. La 5NF est la forme la plus rigoureuse et peut s'avérer utile pour les bases de données complexes présentant des schémas d'interrogation spécifiques.
Comment puis-je décider si je dois normaliser en 5NF ?
Analysez soigneusement vos requêtes et votre modèle de données. Si vous avez besoin de joindre plusieurs tableaux pour extraire des informations qui pourraient être théoriquement dérivées des tableaux eux-mêmes, la méthode 5NF peut être envisagée. Toutefois, il convient de toujours mettre en balance la complexité et les gains de performance potentiels. Vous pouvez vous référer à la section 5NF, où un scénario a été utilisé pour une meilleure compréhension.
Professionnel expérimenté des données et écrivain passionné par l'autonomisation des experts en herbe dans le domaine des données.
Poursuivez votre voyage SQL dès aujourd'hui !
cours
Jointure de données en SQL
cours