web-dev-qa-db-fra.com

Pourquoi les gens recommandent-ils de ne pas utiliser le nom "Id" pour une colonne d'identité?

On m'a appris à ne pas utiliser le nom Id pour la colonne d'identité de mes tables, mais dernièrement, je ne l'ai utilisé que de toute façon parce que c'est simple, court et très descriptif sur ce que sont réellement les données.

J'ai vu des gens suggérer de préfixer Id avec le nom de la table, mais cela semble simplement faire plus de travail pour la personne qui écrit les requêtes SQL (ou le programmeur si vous utilisez un ORM comme Entity Framework), en particulier sur des noms de table plus longs tels que CustomerProductId ou AgencyGroupAssignementId

Un fournisseur tiers que nous avons engagé pour créer quelque chose pour nous a en fait nommé toutes leurs colonnes d'identité Ident juste pour éviter d'utiliser Id. Au début, je pensais qu'ils l'avaient fait parce que Id était un mot-clé, mais quand je l'ai examiné, j'ai trouvé que Id n'était pas un mot-clé dans SQL Server 2005, ce que nous utilisons .

Alors pourquoi les gens recommandent-ils de ne pas utiliser le nom Id pour une colonne d'identité?

Edit: Pour clarifier, je ne demande pas quelle convention de nommage utiliser, ni d'arguments pour utiliser une convention de nommage par rapport à l'autre. Je veux juste savoir pourquoi il est recommandé de ne pas utiliser Id pour le nom de la colonne d'identité.

Je suis un seul programmeur, pas un dba, et pour moi, la base de données n'est qu'un endroit pour stocker mes données. Étant donné que je crée généralement de petites applications et que j'utilise généralement un ORM pour l'accès aux données, un nom de champ commun pour le champ d'identité est beaucoup plus facile à utiliser. Je veux savoir ce que je manque en faisant cela, et s'il y a vraiment de bonnes raisons pour moi de ne pas le faire.

69
Rachel

Voici un résumé de toutes les réponses sur les avantages obtenus de la convention de ne pas utiliser un nom commun pour toutes les clés primaires:

  • Moins d'erreurs, car les champs d'identité n'ont pas le même nom

    Vous ne pouvez pas écrire par erreur une requête qui se joint à B.Id = B.Id Au lieu de A.Id = B.Id, Car les champs d'identité ne seront jamais nommés exactement de la même manière.

  • Noms de colonne plus clairs.

    Si vous regardez une colonne nommée CustomerId, vous savez immédiatement quelles données se trouvent dans cette colonne. Si le nom de la colonne était quelque chose de générique comme Id, vous devez également connaître le nom de la table pour savoir quelles données la colonne contient.

  • Évite les alias de colonne inutiles

    Vous pouvez maintenant écrire SELECT CustomerId, ProductId À partir d'une requête qui joint Customers avec Products, au lieu de SELECT Customer.Id as CustomerId, Products.Id as ProductId

  • Autorise la syntaxe JOIN..USING

    Vous pouvez joindre des tables avec la syntaxe Customer JOIN Products USING (CustomerId), au lieu de Customer JOIN Products ON Customer.Id = Products.Id

  • La clé est plus facile à trouver dans les recherches

    Si vous recherchez le champ d'identité d'un client dans une grande solution, la recherche de CustomerId est beaucoup plus utile que la recherche de Id

Si vous pouvez penser à d'autres avantages de cette convention de dénomination, faites-le moi savoir et je l'ajouterai à la liste.

Que vous choisissiez d'utiliser des noms de colonne uniques ou identiques pour les champs d'identité, cela dépend de vous, mais peu importe ce que vous choisissez, veuillez être cohérent :)

28
Rachel

Le préfixe du nom de table a de très bonnes raisons.

Considérer:

TableA (id int identity, stringdata varchar(max))

TableB (id int identity, stringdata varchar(max))

Nous voulons DELETE à partir de TableA enregistrements qui existent dans les deux tables. Assez simple, nous allons juste faire un INNER JOIN:

DELETE a
FROM 
  TableA A
INNER JOIN 
  TableB B
    ON b.id = B.id

....et nous venons d'effacer tout TableA. Nous avons comparé par inadvertance l'ID de B à lui-même - chaque enregistrement correspond, et chaque enregistrement a été supprimé.

Si les champs avaient été nommés TableAId et TableBId cela serait impossible (Invalid field name TableAid in TableB).

Personnellement, je n'ai aucun problème à utiliser le nom id dans une table, mais c'est vraiment une meilleure pratique de le faire précéder du nom de la table (ou du nom de l'entité, si TableA était des personnes alors PeopleId fonctionnerait bien aussi) pour éviter de se comparer accidentellement au mauvais champ et de faire exploser quelque chose.

Cela rend également très évident d'où viennent les champs dans les longues requêtes avec beaucoup de JOINs.

46
JNK

C'est surtout pour empêcher les clés étrangères de devenir une douleur énorme. Supposons que vous ayez deux tables: Customer et CustomerAddress. La clé primaire pour les deux est une colonne nommée id, qui est une colonne d'identité (int).

Vous devez maintenant avoir l'ID client référencé à partir de CustomerAddress. Vous ne pouvez pas nommer l'ID de colonne, évidemment, alors vous allez avec customer_id.

Cela conduit à quelques problèmes. Tout d'abord, vous devez toujours vous rappeler quand appeler la colonne "id" et quand l'appeler "customer_id". Et si vous vous trompez, cela mène au deuxième problème. Si vous avez une grande requête avec une douzaine de jointures et qu'elle ne renvoie aucune donnée, amusez-vous à jouer à Where's Waldo et à traquer cette faute de frappe:

ON c.id = ca.id

Oups, aurait dû être ON c.id = ca.customer_id. Ou mieux encore, nommez vos colonnes d'identité de manière descriptive, afin qu'elles puissent être ON c.customer_id = ca.customer_id. Ensuite, si vous utilisez accidentellement le mauvais alias de table quelque part, customer_id ne sera pas une colonne dans cette table, et vous obtiendrez une erreur de compilation Nice, plutôt que des résultats vides et un plissement de code ultérieur.

Certes, il y a des cas où cela n'aide pas, comme si vous avez besoin de plusieurs relations de clé étrangère d'une table à une autre, mais nommer toutes les clés primaires "id" n'y aide pas non plus.

36
db2

Pour copier ma réponse à partir de la question liée:

Il y a une situation où coller "ID" sur chaque table n'est pas la meilleure idée: le mot clé USING, s'il est pris en charge. Nous l'utilisons souvent dans MySQL.

Par exemple, si vous avez fooTable avec la colonne fooTableId et barTable avec la clé étrangère fooTableId, alors vos requêtes peuvent être construites comme telles:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Il enregistre non seulement la saisie, mais est beaucoup plus lisible par rapport à l'alternative:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
12
Izkata

Après avoir normalisé un schéma de base de données pour limiter la redondance, les tables sont divisées en tables plus petites avec des relations établies (une à une, une à plusieurs, plusieurs à plusieurs). Dans le processus, des champs uniques de la table d'origine peuvent apparaître dans plusieurs tables normalisées.

Par exemple, une base de données pour un blog pourrait ressembler à ceci sous sa forme non normalisée, en supposant une contrainte unique sur le Author_Nickname.

| Author_Nickname | Author_Email | Post_Title | Post_Body |
+-----------------+--------------+------------+-----------+
| dave            | [email protected]   | Blah       | Bla bla   |
| dave            | [email protected]   | Stuff      | I like    |
| sophie          | [email protected]     | Lorem      | Ipsum     |

La normalisation produirait deux tableaux:

Auteur:

| Author_Nickname | Author_Email |
+-----------------+--------------+
| dave            | [email protected]   |
| sophie          | [email protected]     |

Publier

| Author_Nickname | Post_Title | Post_Body |
+-----------------+------------+-----------+
| dave            | Blah       | Bla bla   |
| dave            | Stuff      | I like    |
| sophie          | Lorem      | Ipsum     |

Ici, Author_Nickname serait une clé primaire pour la table d'auteur et une clé étrangère dans la table de publication. Même si Author_Nickname apparaît dans deux tableaux, il correspond toujours à une seule unité d'information, c'est-à-dire. chaque nom de colonne correspond à un seul champ.

Dans de nombreux cas, il ne peut pas y avoir de contrainte unique sur les champs d'origine, donc un champ artificiel numérique est utilisé à la place comme clé primaire. Cela ne change pas le fait que chaque nom de colonne représente toujours un seul champ. Dans la conception de base de données traditionnelle, les noms de colonnes individuels correspondent à des champs uniques, même s'ils ne sont pas des clés. (par exemple, on utiliserait part.partname et client.clientname plutôt que part.name et client.name ). C'est la raison de l'existence du INNER JOIN ... USING <key> et le NATURAL JOIN syntaxes.

Cependant, de nos jours, et avec les couches ORM facilement disponibles dans de nombreuses langues, les bases de données sont souvent conçues comme une couche de persistance pour les langues OO, dans lesquelles il est naturel que les variables qui ont le même rôle dans différentes classes sont appelés les mêmes ( part.name et client.name , pas part.partname et client.clientname ). Dans un tel contexte, J'ai tendance à utiliser 'ID' pour mes clés primaires.

9
stilgar

Un fournisseur tiers que nous avons engagé pour créer quelque chose pour nous a en fait nommé toutes leurs colonnes d'identité Ident juste pour éviter d'utiliser Id.

Utiliser "Ident" au lieu de "Id" ne résout vraiment rien si "Ident" finit par être utilisé sur toutes leurs tables.

Il y a un bon article sur Conventions de codage SQL sur le Drupal qui indique une bonne pratique pour cette situation:

Il est recommandé de préfixer les noms de table avec le nom du module pour éviter d'éventuels conflits d'espace de noms.

De ce point de vue, CustomerProductId et AgencyGroupAssignmentId ont un sens à utiliser. Oui, c'est assez verbeux. Vous pouvez le raccourcir, mais le plus gros point à considérer est si le développeur qui vous suit comprendra ou non ce que vous vouliez dire . Les ID précédés de noms de table détaillés ne doivent pas laisser d'ambiguïté sur ce qu'ils sont. Et (pour moi) c'est plus important que d'enregistrer quelques touches.

8
Aaron

Je nomme mes colonnes CustomerID au lieu de ID, donc chaque fois que je tape

FROM dbo.Customers AS c JOIN dbo.CustomerOrders AS o

L'invite SQL suggère immédiatement ce qui suit

ON c.CustomerID = o.CustomerID 

Cela me fait gagner quelques touches. Pourtant, je pense que les conventions de dénomination sont très subjectives et en tant que telles, je n'ai pas d'opinion forte d'une manière ou d'une autre.

7
A-K

C'est la même raison pour laquelle vous ne nommeriez pas tous vos champs varchar quelque chose comme "UserText" et "UserText1", ou pourquoi vous n'utiliseriez pas "UserDate" et "UserDate1".

Typiquement, si vous avez un champ d'identité dans une table, c'est votre clé primaire. Comment construiriez-vous une table enfant avec une clé étrangère vers une table parent si la clé primaire dans les deux tables était id?

Tout le monde n'est pas d'accord avec cette méthode, mais dans mes bases de données, j'attribue une abréviation unique à chaque table. Le PK de cette table serait nommé PK_ [abbrv] ID. SI cela est utilisé comme FK n'importe où, j'utiliserais FK_ [abbrv] ID. Maintenant, je n'ai aucune conjecture sur la détermination des relations entre les tables.

5
DForck42

Fondamentalement, pour la même raison, vous ne nommez généralement pas les paramètres paramètre1, paramètre2 ... c'est précis, mais pas descriptif. Si vous voyez TableId, alors vous pouvez probablement supposer en toute sécurité qu'il est utilisé pour contenir un pk pour Table, quel que soit le contexte.

Quant à celui qui a utilisé Ident, il rate complètement le point, étant donné le choix entre Ident et Id use Id. Ident est encore plus déroutant que Id.

Hors contexte, Id peut être supposé être la clé primaire d'une table (pas extrêmement utile à moins que l'id ne soit un guide), mais Ident ne vous le dit même pas (ou du moins moi). Je finirais par comprendre que Ident est l'abréviation de l'identité (d'une manière ou d'une autre), mais le temps que je passais à comprendre cela serait perdu.

5
jmoreno

Utilisez un préfixe pour que le même nom puisse être utilisé dans les contextes de clé primaire et de clé étrangère, afin de pouvoir effectuer natural join/join ... using.

3
DrPizza