Implémentation d'une relation un à zéro ou une dans SQL


10

Disons que je conçois une base de données pour un scénario où il existe une relation un à zéro ou un (1-0..1). Par exemple:

  • Il existe un ensemble d' utilisateurs , et certains utilisateurs peuvent également être des clients .

J'ai donc créé les deux tableaux correspondants, userset customers, mais…

… Quelle est la meilleure façon de représenter et de mettre en œuvre cette situation dans une plate-forme SQL donnée? J'ai envisagé deux solutions possibles:

  1. Dans le userstableau, ajoutez la customercolonne qui peut être une référence FOREIGN KEY customersou une NULLmarque.

  2. Dans le customerstableau, incluez une usercolonne (définie avec une UNIQUEcontrainte) qui pointe vers le userstableau.

J'ai déjà posé une question similaire dans certains forums, mais la réponse était essentiellement «tout ce dont vous avez besoin», «tout ce que vous pensez commode». Je n'aime pas ce genre de réponse. Je veux plutôt un morceau sérieux de théorie DB, une réponse bien fondée. Où puis-je lire sur les relations 1-0..1?

Réponses:


10

Je veux un morceau sérieux de théorie DB

La théorie relationnelle moderne rejette les valeurs nulles , ce qui semblerait invalider immédiatement votre option 1. Cependant, cet homme de paille peut être éliminé en remplaçant la valeur par défaut null par une valeur par défaut, par exemple un client "factice" créé uniquement pour modéliser explicitement "n'est pas un client" correspondance.

Je pense que votre option 2 est la plus théorique, car, contrairement à l'option 1 modifiée, les relations peuvent être sous la sixième forme normale (6NF), étant une forme normale de projection-jointure et la forme normale la plus élevée possible.

J'ai également entendu parler d'une règle empirique de conception qui stipule qu'une relation doit modéliser SOIT une entité OU la relation entre les entités mais jamais les deux, ce qui me semble sensé. Encore une fois, cela favoriserait l'option 2. Cependant, j'ai entendu parler de cette règle empirique il y a de nombreuses années, ne me souviens pas où et ne peut offrir aucune base théorique sérieuse (autre que 6NF comme mentionné ci-dessus).


2

On vous a donné la bonne réponse en partie. La vraie réponse vient de votre modèle de données et de la façon dont il a été normalisé. Une clé est de savoir comment vous arrivez à la relation:

  • La customerstable se compose d'un certain nombre de champs considérés pour la userstable qui appartiennent au concept du client et sont nuls à moins que l'utilisateur ne soit également un client (sous-type d'utilisateur). Dans ce cas, la customerstable hérite de la clé primaire de la userstable. (Il est possible de créer plusieurs sous-types qui peuvent ou non se chevaucher.)

  • Le customerstableau se compose d'un certain nombre de champs liés au concept client, mais pas nécessairement au concept utilisateur. Le client est une table solide et ne dépend pas du concept utilisateur. (La suppression de la userstable n'aurait pas d'impact significatif sur la conception de la table clients.) Dans ce cas, la table clients obtient sa propre clé primaire.

Ce que vous avez est un cas spécial de relation un à plusieurs facultative où la limite supérieure est 1. Considérez-la des deux côtés: Serait-il possible qu'un utilisateur ait plusieurs clients ou qu'un client ait plusieurs utilisateurs? Si c'est le cas, vous devrez remodeler vos données.

L'ajout de la user-idclé étrangère à la customerstable peut être considéré comme un meilleur choix car elle mappe correctement la relation un à plusieurs (limite supérieure 1) et évite un champ nullable. Pour appliquer la limite supérieure, l'index de clé étrangère doit être unique. Cela se produira automatiquement si la clé primaire est la user-id.

L'ajout de la customer-idclé étrangère facultative à la userstable applique la limite supérieure de 1 dans la relation, mais inverse la dépendance.


1

Avez-vous envisagé une approche un peu plus complexe mais flexible. La table parent est "personne" (ou "entité" selon la complexité que vous souhaitez avoir). Ensuite, la table client et la table utilisateur ont chacune un FK pour la table personne. La table personne contient des détails personnels tandis que les tables client et utilisateur ne contiennent que des attributs associés à un utilisateur ou un client. Souvent, les adresses (e-mail et courrier postal), les numéros de téléphone, etc. sont également représentés dans des tableaux séparés avec des tables de mappage pour permettre des situations plusieurs à plusieurs. Il s'agit d'un modèle relativement courant que vous pouvez trouver sur un certain nombre de sites de référence.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.