web-dev-qa-db-fra.com

Convention de dénomination de clé primaire / clé étrangère

Dans notre groupe de développement, nous avons un débat qui fait rage concernant la convention de dénomination pour les clés primaires et étrangères. Il y a essentiellement deux écoles de pensée dans notre groupe:

1:

Primary Table (Employee)   
Primary Key is called ID

Foreign table (Event)  
Foreign key is called EmployeeID

ou

2:

Primary Table (Employee)  
Primary Key is called EmployeeID

Foreign table (Event)  
Foreign key is called EmployeeID

Je préfère ne pas dupliquer le nom du tableau dans aucune des colonnes (je préfère donc l'option 1 ci-dessus). Sur le plan conceptuel, il est cohérent avec de nombreuses pratiques recommandées dans d'autres langues, où vous n'utilisez pas le nom de l'objet dans ses noms de propriété. Je pense que nommer la clé étrangère EmployeeID (ou Employee_ID pourrait être mieux) indique au lecteur qu'il s'agit de la colonne ID de la table Employee.

Certains préfèrent l'option 2 où vous nommez la clé primaire préfixée avec le nom de la table afin que le nom de la colonne soit le même dans toute la base de données. Je vois ce point, mais vous ne pouvez maintenant pas distinguer visuellement une clé primaire d'une clé étrangère.

En outre, je pense qu'il est redondant d'avoir le nom de la table dans le nom de la colonne, car si vous pensez à la table comme une entité et à une colonne comme une propriété ou un attribut de cette entité, vous la considérez comme l'attribut ID du Employee, pas l'attribut EmployeeID d'un employé. Je ne vais pas demander à mon collègue quel est son PersonAge ou PersonGender. Je lui demande quel est son âge.

Donc, comme je l'ai dit, c'est un débat qui fait rage et nous continuons encore et encore à ce sujet. Je suis intéressé à obtenir de nouvelles perspectives.

89
Jeremy

Ça n'a pas vraiment d'importance. Je n'ai jamais rencontré de système où il y a une réelle différence entre le choix 1 et le choix 2.

Jeff Atwood avait un excellent article il y a quelque temps sur ce sujet. Fondamentalement, les gens débattent et discutent les plus furieusement des sujets sur lesquels ils ne peuvent pas être prouvés faux. Ou sous un angle différent, ces sujets qui ne peuvent être gagnés que par des arguments de dernier homme basés sur l'endurance de style flibustier.

Choisissez-en un et dites-lui de se concentrer sur les problèmes qui ont réellement un impact sur votre code.

EDIT: Si vous voulez vous amuser, demandez-leur de préciser pourquoi leur méthode est supérieure pour les références de table récursives.

48
Russell Steen

Si les deux colonnes ont le même nom dans les deux tables (convention n ° 2), vous pouvez utiliser la syntaxe USING dans SQL pour enregistrer du typage et du bruit standard:

SELECT name, address, amount
  FROM employees JOIN payroll USING (employee_id)

Un autre argument en faveur de la convention n ° 2 est que c'est la façon dont le modèle relationnel a été conçu.

La signification de chaque colonne est partiellement transmise en l'étiquetant avec le nom du domaine correspondant.

69
Steven Huwig

Je pense que cela dépend de la façon dont votre demande est organisée. Si vous utilisez ORM ou concevez vos tableaux pour représenter des objets, l'option 1 peut être pour vous.

J'aime coder la base de données comme sa propre couche. Je contrôle tout et l'application n'appelle que des procédures stockées. Il est agréable d'avoir des jeux de résultats avec des noms de colonnes complets, surtout lorsqu'il y a plusieurs tables jointes et plusieurs colonnes retournées. Avec ce type d'application, j'aime l'option 2. J'aime vraiment voir les noms de colonnes correspondre sur les jointures. J'ai travaillé sur d'anciens systèmes où ils ne correspondaient pas et c'était un cauchemar,

12
KM.

Aucune des deux conventions ne fonctionne dans tous les cas, alors pourquoi en avoir une? Utiliser le bon sens...

par exemple, pour une table auto-référencée, lorsqu'il y a plus d'une colonne FK qui auto-référence la PK de la même table, vous DEVEZ violer les deux "normes", car les deux colonnes FK ne peuvent pas être nommées de la même manière ... par exemple , EmployeeTable avec EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK, ...

3
Charles Bretana

Je suis d'accord qu'il y a peu de choix entre eux. Pour moi, une chose beaucoup plus importante à propos de l'une ou l'autre norme est la partie "standard".

Si les gens commencent à "faire leur propre chose", ils devraient être suspendus par leurs frères et sœurs. A MON HUMBLE AVIS :)

3
MatBailie

Avez-vous pensé aux éléments suivants?

Primary Table (Employee)   
Primary Key is PK_Employee

Foreign table (Event)  
Foreign key is called FK_Employee
3
Wouter

J'aime la convention n ° 2 - en recherchant ce sujet et en trouvant cette question avant de poster la mienne, j'ai rencontré le problème où:

Je sélectionne * dans une table avec un grand nombre de colonnes et je la joins à une deuxième table qui a également un grand nombre de colonnes. Les deux tables ont une colonne "id" comme clé primaire, et cela signifie que je dois sélectionner spécifiquement chaque colonne (pour autant que je sache) afin de rendre ces deux valeurs uniques dans le résultat, à savoir:

SELECT table1.id AS parent_id, table2.id AS child_id

Bien que l'utilisation de la convention # 2 signifie que j'aurai toujours quelques colonnes dans le résultat avec le même nom, je peux maintenant spécifier qui id dont j'ai besoin (parent ou enfant) et, comme Steven Huwig l'a suggéré, le USING simplifie encore les choses.

2
JYelton

La convention que nous utilisons là où je travaille est assez proche de A, à l'exception que nous nommons les tables au pluriel (c'est-à-dire "employés") et utilisons des traits de soulignement entre le nom de la table et la colonne. L'avantage est que pour faire référence à une colonne, il s'agit soit de "id_employés", soit de "id.employés", selon la manière dont vous souhaitez y accéder. Si vous devez spécifier de quelle table provient la colonne, "employees.employees _ id" est définitivement redondant.

2
Jarett Millard

J'ai toujours utilisé serId comme PK sur une table et serId sur une autre table comme FK. pense sérieusement à utiliser serIdPK et serIdFK comme noms pour identifier les uns des autres. Cela m'aidera à identifier rapidement PK et FK en regardant les tables et il semble que cela clarifiera le code lors de l'utilisation de PHP/SQL pour accéder aux données, ce qui le rendra plus facile à comprendre. Surtout quand quelqu'un d'autre regarde mon code.

2
Ross

Si vous regardez le code d'application, pas seulement les requêtes de base de données, certaines choses me semblent claires:

  1. Les définitions de table correspondent généralement directement à une classe qui décrit un objet, elles doivent donc être singulières. Pour décrire une collection d'un objet, j'ajoute généralement "Array" ou "List" ou "Collection" au nom singulier, car cela plus clairement que l'utilisation de pluriels indique non seulement qu'il s'agit d'une collection, mais quel type de collection c'est. Dans cette vue, je vois un nom de table non pas le nom de la collection, mais le nom du type d'objet dont il s'agit d'une collection. Un DBA qui n'écrit pas de code d'application peut manquer ce point.

  2. Les données que je traite utilisent souvent "ID" à des fins d'identification non clés. Pour éliminer la confusion entre les "ID" clés et les "ID" non clés, pour le nom de la clé primaire, nous utilisons "Key" (c'est ce que c'est, n'est-ce pas?) Préfixé avec le nom de la table ou une abréviation de le nom de la table. Ce préfixe (et je le réserve uniquement pour la clé primaire) rend le nom de la clé unique, ce qui est particulièrement important car nous utilisons des noms de variables qui sont les mêmes que les noms des colonnes de la base de données, et la plupart des classes ont un parent, identifié par le nom de la clé parent. Cela est également nécessaire pour vous assurer qu'il ne s'agit pas d'un mot clé réservé, ce que "Clé" est seul. Pour faciliter la cohérence des noms de variables de clé et pour fournir des programmes qui effectuent des jointures naturelles, les clés étrangères ont le même nom que celui utilisé dans le tableau dans lequel elles sont la clé primaire. J'ai rencontré plus d'une fois des programmes qui fonctionnent beaucoup mieux de cette façon en utilisant des jointures naturelles. Sur ce dernier point, j'avoue un problème avec les tables auto-référencées, que j'ai utilisées. Dans ce cas, je ferais une exception à la règle de dénomination des clés étrangères. Par exemple, j'utiliserais ManagerKey comme clé étrangère dans la table Employee pour pointer vers un autre enregistrement de cette table.

2
Bruce Patin

J'utilise la convention # 2. Je travaille avec un modèle de données hérité maintenant où je ne sais pas ce que signifie une table donnée. Où est le mal d'être verbeux?

1
OMG Ponies

Que diriez-vous de nommer la clé étrangère

id_rôle

où rôle est le rôle que l'entité référencée a relativement à la table à portée de main. Cela résout le problème de la référence récursive et de plusieurs fks sur la même table.

Dans de nombreux cas, il sera identique au nom de la table référencée. Dans ce cas, il devient identique à l'une de vos propositions.

En tout cas, les longs arguments havin sont une mauvaise idée

1
Jens Schauder

"Où en" employé INNER JOIN order ON order.employee_id = employee.id "y a-t-il un besoin de qualification supplémentaire?".

Il n'y a pas besoin de qualification supplémentaire car la qualification dont j'ai parlé est déjà là.

"la raison pour laquelle un utilisateur professionnel se réfère à l'ID de commande ou à l'ID d'employé est de fournir un contexte, mais au niveau de la base de données, vous avez déjà un contexte car vous vous référez à la table".

Je vous en prie, dites-moi, si la colonne est nommée "ID", comment cela se fait-il "de référencer [sic] à la table", sauf en qualifiant cette référence à la colonne ID exactement de la manière dont j'ai parlé?

0
Erwin Smout