web-dev-qa-db-fra.com

Est-ce bien d'avoir une clé étrangère comme clé primaire?

J'ai deux tables:

  • Utilisateur (nom d'utilisateur, mot de passe)
  • Profil (profileId, genre, date de naissance, ...)

J'utilise actuellement cette approche: chaque enregistrement de profil a un champ nommé "userId" comme clé étrangère qui renvoie à la table User. Lorsqu'un utilisateur s'inscrit, son enregistrement de profil est créé automatiquement.

La suggestion de mon ami me confond: avoir le champ "userId" comme clé étrangère et primaire et supprimer le champ "profileId". Quelle approche est la meilleure?

80
Duc Tran

Les clés étrangères sont presque toujours "Autoriser les doublons", ce qui les rendrait inappropriées en tant que clés primaires.

Au lieu de cela, recherchez un champ qui identifie de manière unique chaque enregistrement de la table ou ajoutez un nouveau champ (un entier auto-incrémenté ou un GUID) agissant comme clé primaire.

La seule exception à cette règle concerne les tables avec une relation un-à-un , où la étrangère clé et primaire la clé de la table liée sont identiques.

107
Robert Harvey

Les clés primaires doivent toujours être uniques, les clés étrangères doivent autoriser des valeurs non uniques si la table est une relation un-à-plusieurs. Il est tout à fait judicieux d'utiliser une clé étrangère comme clé primaire si la table est connectée par une relation un-à-un, et non par un lien un-à-plusieurs. Si vous voulez que le même enregistrement d'utilisateur ait la possibilité d'avoir plus d'un enregistrement de profil associé, utilisez une clé primaire distincte, sinon restez avec ce que vous avez.

31
kotekzot

Il est généralement considéré comme une mauvaise pratique d’avoir une relation de un à un. En effet, vous pouvez simplement représenter les données dans une seule table et obtenir le même résultat.

Cependant, dans certains cas, vous ne pourrez peut-être pas apporter ces modifications à la table à laquelle vous faites référence. Dans ce cas, l'utilisation de la clé étrangère en tant que clé primaire ne pose aucun problème. Il peut être utile d’avoir une clé composite composée d’une clé primaire unique incrémentée automatiquement et de la clé étrangère.

Je travaille actuellement sur un système où les utilisateurs peuvent se connecter et générer un code d'enregistrement à utiliser avec une application. Pour des raisons que je n'entrerai pas dans les détails, je ne peux pas simplement ajouter les colonnes requises à la table des utilisateurs. Donc, je vais sur une route one to one avec la table de codes.

3
Tshsmith

Oui, une clé étrangère peut être une clé primaire dans le cas d'une relation un à un entre ces tables.

3
Riaj Ferdous

Oui, il est légal d'avoir une clé primaire étant une clé étrangère. C'est une construction rare, mais elle s'applique pour:

  • une relation 1: 1. Les deux tables ne peuvent pas être fusionnées en une seule, car des autorisations et des privilèges différents ne s'appliquent qu'au niveau de la table (à partir de 2017, une telle base de données serait impaire).

  • une relation 1: 0..1. Le profil peut exister ou non, selon le type d'utilisateur.

  • les performances sont un problème et la conception agit comme une partition: la table de profil est rarement consultée, hébergée sur un disque séparé ou possède une stratégie de partage différente de celle de la table users. Cela n'aurait aucun sens si le stockage de soulignement est en colonnes.

3
user9016329

Je ne ferais pas ça. Je garderais le profileID comme clé primaire de la table Profile

Une clé étrangère est juste une contrainte référentielle entre deux tables

On pourrait soutenir qu'une clé primaire est nécessaire en tant que cible de toutes les clés étrangères qui y font référence depuis d'autres tables. Une clé étrangère est un ensemble d'une ou de plusieurs colonnes d'une table (pas nécessairement une clé candidate, encore moins la clé primaire de cette table) pouvant contenir la ou les valeurs trouvées dans la ou les colonnes de clé primaire de autre table. Nous devons donc avoir une clé primaire pour correspondre à la clé étrangère. Ou devons-nous? Le seul objectif de la clé primaire dans la paire clé primaire/clé étrangère est de fournir une jointure sans ambiguïté - afin de maintenir l'intégrité référentielle par rapport à la table "étrangère" qui contient la clé primaire référencée. Cela garantit que la valeur à laquelle la clé étrangère fait référence sera toujours valide (ou nulle si elle est autorisée).

http://www.aisintl.com/case/primary_and_foreign_key.html

2

Cela dépend de l'entreprise et du système.

Si votre userId est unique et le sera tout le temps, vous pouvez utiliser userId comme clé primaire. Mais si vous souhaitez développer votre système, cela rendra les choses difficiles. Je vous conseille d'ajouter une clé étrangère dans l'utilisateur de la table pour établir une relation avec le profil de la table plutôt que d'ajouter une clé étrangère dans le profil de la table.

1
Vincent Cai

Réponse courte: DÉPENDRE .... Dans ce cas particulier, cela pourrait aller. Cependant, les experts le recommanderont à chaque fois; y compris votre cas.

Pourquoi?

Les clés sont rarement uniques dans les tables lorsqu'elles sont étrangères (créées dans une autre table) à la table en question. Par exemple, un ID d'article peut être unique dans une table ITEMS, mais pas dans une table ORDERS, car le même type d'article existera probablement dans un autre ordre. De même, les ID de commande peuvent être uniques (peuvent être) dans la table ORDERS, mais pas dans une autre table telle que ORDER_DETAILS où une commande avec plusieurs éléments de ligne peut exister et pour interroger un élément particulier dans un ordre particulier, vous avez besoin de la concaténation de deux éléments. FK (order_id et item_id) en tant que PK pour cette table.

Je ne suis pas un expert en bases de données, mais si vous pouviez justifier logiquement d'avoir une valeur générée automatiquement en tant que votre PK, je le ferais. Si ce n'est pas pratique, alors une concaténation de deux (ou peut-être plus) FK pourrait vous servir de PK. MAIS, je ne peux pas penser à un cas où une seule valeur FK peut être justifiée en tant que PK.

0
hfontanez