Les relations un-à-plusieurs sont l'une des relations de base de données les plus courantes. Si vous souhaitez savoir quand et comment utiliser les relations un-à-plusieurs, cet article est un excellent point de départ.
Vous utiliserez sûrement des relations un-à-plusieurs pour stocker des informations dans n'importe quelle base de données relationnelle, que vous conceviez un logiciel au niveau de l'entreprise ou que vous créiez simplement une base de données simple pour suivre la collection de timbres de votre oncle.
Une brève introduction au modèle relationnel
Les bases de données relationnelles sont un composant central de toute application transactionnelle moderne. Le modèle relationnel est composé de tables (données organisées en lignes et en colonnes) qui ont au moins une clé unique qui identifie chaque ligne. Chaque table représente une entité. C'est ce que montre l'exemple suivant, une version très simple d'un tableau représentant les commandes client :
Le diagramme ci-dessus, que j'ai créé en ligne avec Vertabelo, a une seule table. Chaque ligne du tableau représente une commande et chaque colonne (également appelée attribut ) représente chaque élément d'information individuel contenu dans une commande.
Pour ceux qui ne sont pas encore familiarisés avec l'outil de conception Vertabelo, l'article Quels sont les symboles utilisés dans les diagrammes ER ? explique les symboles et les conventions utilisés. Vous pouvez également en savoir plus sur les modèles relationnels et les bases de données en utilisant notre cours de modélisation de base de données.
Que sont les relations et pourquoi en avons-nous besoin ?
Si nous examinons de plus près le tableau utilisé dans l'exemple précédent, nous verrons qu'il ne représente pas vraiment une commande complète. Il ne contient pas toutes les informations que vous attendez de lui. Vous remarquerez qu'il n'inclut aucune donnée relative au client qui a passé la commande, ni rien sur les produits ou services commandés.
Que devons-nous faire pour compléter cette conception afin de stocker les données de commande ? Devrions-nous ajouter des informations sur le client et le produit à la commande ? table? Cela nécessiterait l'ajout de nouvelles colonnes (attributs) pour les noms de clients, les identifiants fiscaux, les adresses, etc., comme indiqué ci-dessous :
"OrderID" | "Date de commande" | "Montant de la commande" | Client | "Adresse du client" | "Téléphone du client" | "TaxIdentifier" |
---|---|---|---|---|---|---|
1 | juin-23 | 10 248,15 $ | International Services Ltd | 1247 St River Blvd, Charlotte, Caroline du Nord | (555) 478-8741 | IS789456 |
2 | juin-27 | 14 785,45 $ | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, Californie | (555) 774-8888 | WM321456 |
3 | juil-01 | 7 975 00 $ | First State Provisioning LLC | Autoroute 444 Nord, Houston, Texas | (555) 698-7411 | FS947561 |
4 | juil-03 | 6 784,25 $ | International Services Ltd | 1247 St River Blvd, Charlotte, Caroline du Nord | (555) 478-8741 | IS789456 |
5 | juil-07 | 21 476,10 $ | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, Californie | (555) 774-8888 | WM321456 |
6 | juil-12 | 9 734,00 $ | First State Provisioning LLC | Autoroute 444 Nord, Houston, Texas | (555) 698-7411 | FS947561 |
7 | juil-17 | 14 747,45 $ | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, Californie | (555) 774-8888 | WM321456 |
8 | juil-21 | 19 674,85 $ | International Services Ltd | 1247 St River Blvd, Charlotte, Caroline du Nord | (555) 478-8741 | IS789456 |
Si nous faisons cela, nous rencontrerons bientôt des problèmes. La plupart des clients passent plus d'une commande, donc ce système stockera les informations client plusieurs fois, une fois pour chaque commande de chaque client. Cela ne semble pas être une décision intelligente.
De plus, que se passe-t-il lorsqu'un client change de numéro de téléphone ? Si quelqu'un a besoin d'appeler le client, il peut trouver l'ancien numéro sur les commandes précédentes, à moins que quelqu'un ne mette à jour des centaines (voire des milliers) de commandes existantes avec les nouvelles informations. Et il en irait de même pour tout autre changement.
Un modèle relationnel nous oblige à définir chaque entité comme une table distincte et à établir des relations entre elles. Stocker toutes les informations dans un seul tableau ne fonctionne tout simplement pas.
Il existe plusieurs types de relations entre les tables, mais la plus courante est probablement la relation un-à-plusieurs, souvent écrite sous la forme 1:N. Ce type de relation signifie qu'une ligne d'une table (généralement appelée table parent) peut avoir une relation avec plusieurs lignes d'une autre table (généralement appelée table enfant). Voici quelques exemples courants de relations un-à-plusieurs :
- Un constructeur automobile fabrique de nombreux modèles différents, mais un modèle de voiture particulier n'est construit que par un seul constructeur automobile.
- Un client peut effectuer plusieurs achats, mais chaque achat est effectué par un seul client.
- Une entreprise peut avoir plusieurs numéros de téléphone, mais un numéro de téléphone appartient à une seule entreprise.
Il existe également d'autres types de relations entre les tables; si vous voulez en savoir plus à leur sujet, consultez cet article sur les relations plusieurs-à-plusieurs.
Revenons à notre exemple de commande initial, le Customer
table serait la table parent et la Order
tablez l'enfant; un client peut avoir plusieurs commandes, alors qu'une commande peut appartenir à un seul client.
Veuillez noter que la définition un-à-plusieurs permet à une ligne de la table parent d'être associée à plusieurs lignes de chaque table enfant, mais elle ne l'exige pas. En fait, la conception permet à un client d'avoir zéro commande (c'est-à-dire un nouveau client qui n'a pas encore effectué son premier achat), une commande (un client relativement nouveau qui a effectué un seul achat) ou plusieurs commandes (un client fréquent).
Affichage des relations un-à-plusieurs dans un diagramme ER
Examinons un exemple plus complet d'un système de commande client simple utilisant un diagramme ER (ou relation d'entité). (Si vous souhaitez en savoir plus sur ces diagrammes, Vertabelo Features :Logical Diagrams est un excellent point de départ.) Voici le modèle :
C'est une conception plus réaliste. Vous remarquerez qu'il y a de nouvelles entités (tables) dans le diagramme, qui contient maintenant les tables Customer
, Order
, Order Detail
, et Product
. Cependant, la chose la plus importante que vous remarquez est qu'il existe maintenant des relations entre les tables .
Dans un modèle de base de données, les relations sont représentées par des lignes reliant deux entités. Les caractéristiques de ces relations sont représentées par différents connecteurs :
- Lorsqu'il n'y a qu'une seule ligne verticale, l'entité la plus proche de ce connecteur n'a qu'une seule ligne affectée par la relation. C'est le "un" dans un vers plusieurs.
- Lorsqu'il existe un connecteur multiligne qui ressemble à une patte d'oie, l'entité la plus proche de ce connecteur a plusieurs lignes affectées par la relation ; c'est le "nombreux".
En regardant l'image et en connaissant la notation, il est simple de comprendre que le schéma définit que chaque Order
peut avoir plusieurs Order Details
et que chaque Order Detail
appartient à une seule Order
.
Implémentation d'une relation un-à-plusieurs entre les tables
Pour définir une relation un-à-plusieurs entre deux tables, la table enfant doit référencer une ligne sur la table parent. Les étapes nécessaires pour le définir sont :
- Ajoutez une colonne à la table enfant qui stockera la valeur de l'identifiant principal. (En fait, la plupart des moteurs de base de données permettent qu'il s'agisse de n'importe quelle clé unique de la table parent, et pas seulement de la clé primaire.) La colonne peut être définie comme obligatoire en fonction des besoins de votre entreprise ; même ainsi, les colonnes de clé étrangère sont généralement créées
Remarque : Il est recommandé de conserver le nom des colonnes de référence identique à celui de la table référencée (parent). Cela rend encore plus simple la compréhension de la relation.
- Ajouter une clé étrangère contrainte sur la table enfant. Cela indique que chaque valeur stockée dans cette nouvelle colonne fait référence à une ligne de la table parent.
Les contraintes de clé étrangère sont une fonctionnalité disponible sur la base de données relationnelle qui impose que :
- Lorsque vous ajoutez une ligne à la table enfant, la valeur de la colonne de référence doit correspondre à une (et une seule) valeur dans la table parent. (C'est pourquoi une colonne ou un ensemble de colonnes constituant une clé primaire ou une clé unique doit être référencé).
- Si quelqu'un essaie de supprimer une ligne de la table parent ou essaie de modifier les valeurs de la clé unique/primaire utilisée comme référence et s'il existe une table enfant qui fait référence à cette ligne, l'opération échouera.
Ces deux fonctionnalités garantissent que la base de données conserve son intégrité. Il n'y a aucune chance de créer des commandes référençant un client inexistant, ni de supprimer un client qui a déjà des commandes.
Création d'une clé étrangère
La syntaxe de clé étrangère dépend généralement du moteur de base de données cible. Une fois que vous avez défini votre modèle logique, vous pouvez utiliser la fonction "Générer un modèle physique..." sur les diagrammes logiques Vertabelo pour transformer votre modèle (indépendant de la base de données) en un modèle physique qui correspond à votre fournisseur de base de données. Vertabelo générera également le script SQL requis qui vous permettra de créer les tables et les relations dans votre base de données cible.
Quelques exemples pratiques de relations 1:N
Passons maintenant en revue quelques exemples de relations un-à-plusieurs dans le monde réel.
Relation un-à-plusieurs utilisant des clés primaires
C'est probablement le scénario le plus courant lors de la définition d'une relation un-à-plusieurs. La table enfant utilise la valeur de clé primaire de la table parent pour établir la relation.
Cet exemple décrit un service de streaming en ligne de base. Passons en revue ce qui est stocké dans chacune des tables et leur relation avec les autres tables de notre modèle :
- Chaque
ServiceType
définit le « comportement » d'un compte (par exemple, combien d'utilisateurs peuvent se connecter au système en même temps, si le compte est activé en Full HD, etc.). Il a une relation avec d'autres entités :- Une relation un-à-plusieurs avec le
Account
, ce qui signifie que chaque type de service peut avoir plusieurs comptes de ce type.
- Une relation un-à-plusieurs avec le
- Chaque
Account
stocke des informations sur un client. Il a deux relations directes avec d'autres entités :- Chaque compte appartient à un seul
ServiceType
, comme expliqué ci-dessus. - Cette table a une relation un-à-plusieurs avec le
Profile
table, ce qui signifie que plusieurs utilisateurs peuvent se connecter à notre système en utilisant le même compte.
- Chaque compte appartient à un seul
- Chaque
Profile
représente un utilisateur dans notre système. Il a deux relations avec d'autres entités :- Chaque profil appartient à un seul
Account
. Cela permet à tous les membres de la famille (ou peut-être à un groupe d'amis) de partager le même compte tandis que chacun a ses propres attributs personnels (par exemple, un nom de profil). - Chaque profil a un
Avatar
unique .
- Chaque profil appartient à un seul
- Chaque
Avatar
est une image qui nous permet d'identifier rapidement chaque utilisateur du compte. Il a une relation avec une autre entité :- Une relation un-à-plusieurs avec
Profile
, ce qui signifie qu'un seul avatar peut être attribué à des profils sur différents comptes.
- Une relation un-à-plusieurs avec
Relations un-à-plusieurs avec des clés uniques naturelles ou de substitution
L'utilisation de clés primaires de substitution est une manière largement acceptée de modéliser des tables. (Les clés primaires de substitution sont générées par la base de données et n'ont aucune valeur commerciale réelle.) Cette méthode produit des clés plus simples à utiliser et ajoute une certaine flexibilité lorsque des modifications sont nécessaires.
Cependant, il existe des situations – par ex. lorsque nous devons interagir avec des systèmes externes - où l'utilisation d'une clé générée dans notre base de données est une mauvaise approche. Pour ces scénarios, il est généralement préférable d'utiliser des clés naturelles, qui sont des valeurs uniques qui font partie de l'entité stockée et ne sont pas générées automatiquement par notre base de données.
L'exemple suivant représente un modèle de données de base d'une organisation qui assure le suivi des véhicules (c'est-à-dire la marque, le modèle, la couleur et l'année de la voiture), leurs propriétaires et toutes les infractions de transit associées. Lorsque nous l'avons défini, nous avons utilisé des clés primaires de substitution pour établir les relations entre les véhicules et les marques, les modèles et les propriétaires, puisque toutes ces informations sont gérées en interne par notre système.
Dans ce système, comment un policier d'une autre ville peut-il signaler une voiture garée illégalement à l'aide de notre clé primaire de véhicule (VehicleID
) ? Ces informations ne sont pas naturellement disponibles sur le véhicule en stationnement, mais la plaque d'immatriculation est là. Cela signifie que le moyen le plus simple de recevoir et d'associer des informations provenant d'une source externe (dans cet exemple, n'importe quel service de police du pays) consiste à utiliser une clé naturelle unique au lieu d'une clé primaire de substitution.
L'implémentation physique de ce diagramme logique pour SQL Server est disponible ici :
Relations un-à-plusieurs sur la même table
Les exemples précédents se concentraient sur les relations entre deux ou plusieurs tables, mais il existe également des scénarios dans lesquels la relation se produit entre les lignes de la même table. Ce type de relation un-à-plusieurs est également appelé relation hiérarchique; il est utilisé dans de nombreux systèmes pour représenter des structures arborescentes, c'est-à-dire un organigramme, un compte du grand livre ou un produit et ses composants.
La première fois que vous aurez besoin de créer ce type de structure, vous serez tenté de définir un tableau pour chacun des niveaux de votre hiérarchie, comme le montre le schéma suivant :
Cette approche présente de nombreux problèmes :
- Tous les tableaux sont presque identiques et stockent des informations identiques.
- Si votre organisation ajoute un nouveau niveau, vous devrez modifier le modèle de données et ajouter une nouvelle table, de nouvelles clés étrangères, etc.
- Si un employé reçoit une promotion, vous devez le supprimer d'un tableau et l'insérer dans un autre.
Par conséquent, la meilleure façon de modéliser ce type de structure consiste à utiliser une table unique qui se référence elle-même, comme illustré dans ce schéma :
Ici, nous voyons un seul Employee
table et une colonne nommée EmployeeID_Manager
. Cette colonne fait référence à un autre employé de la même organisation qui est le superviseur/gestionnaire de l'employé actuel.
J'ai ajouté le _Manager
suffixe pour faire la distinction entre l'ID de la ligne courante et l'ID du gestionnaire. (Nous pourrions utiliser ManagerID
à la place, mais je préfère conserver le nom d'origine de la colonne référencée et, dans les cas où les deux sont dans la même table, ajouter un suffixe qui explique le rôle qu'il a réellement).
Comprendre les relations hiérarchiques est plus complexe que les autres relations un-à-plusieurs. Mais si vous oubliez la table où sont stockées toutes les informations et imaginez qu'il existe en fait différentes tables, chacune représentant un niveau dans la hiérarchie, c'est un peu plus facile à visualiser. Imaginez que vous établissez la relation entre deux entités, puis les combinez en une seule entité.
Quelle est la prochaine ?
Les exemples fournis vous aideront à identifier différents scénarios nécessitant une relation un-à-plusieurs. Vous pouvez commencer à concevoir votre propre structure de base de données à l'aide de Vertabelo Database Modeler, un outil Web qui vous permet non seulement de générer un modèle logique, mais également d'en créer une version physique pour le fournisseur de base de données dont vous avez besoin.
Maintenant, c'est à vous ! Utilisez la section des commentaires pour nous faire part de vos réflexions sur cet article, poser des questions supplémentaires ou partager vos expériences de modélisation de base de données.