Pourquoi nommer la colonne «Id» de la clé primaire d'une table est-il considéré comme une mauvaise pratique? [fermé]


210

Mon professeur de t-sql nous a dit que nommer notre colonne PK "Id" était considéré comme une mauvaise pratique, sans autre explication.

Pourquoi nommer une colonne de table PK "Id" est considéré comme une mauvaise pratique?


27
En fait, ce n’est pas une description et Id signifie "identité", ce qui est très explicite. C'est mon avis.
Jean-Philippe Leclerc

49
Je suis sûr que de nombreux magasins utilisent Id comme nom PK. Personnellement, j'utilise TableId comme convention d'appellation, mais je ne dirais à personne que c'est LA VRAIE MANIÈRE. Il semble que votre professeur essaie simplement de présenter son opinion comme une pratique exemplaire largement acceptée.

22
Définitivement, le type de mauvaise pratique n’est pas si mauvais. Le but est d'être cohérent. Si vous utilisez id, utilisez-le partout ou ne l'utilisez pas.
deadalnix

57
Vous avez une table ... elle s'appelle People, elle a une colonne, Id, que pensez-vous de l'Id? Une voiture? Un bateau? ... non c'est le People Id, c'est tout. Je ne pense pas que ce ne soit pas une mauvaise pratique et qu'il ne soit pas nécessaire de nommer la colonne PK autre que Id.
Jim

38
Alors, l'enseignant se présente devant la classe et vous dit que c'est une mauvaise pratique sans une raison unique? C'est une pratique pire pour un enseignant.
JeffO

Réponses:


247

Je vais sortir et le dire: Ce n'est pas vraiment une mauvaise pratique (et même si c'est le cas, ce n'est pas si mal).

Vous pouvez argumenter (comme l'a souligné Chad ) qu'il peut masquer des erreurs comme dans la requête suivante:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

mais cela peut facilement être atténué en n'utilisant pas de minuscules alias pour les noms de vos tables:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

La pratique de TOUJOURS utiliser des abréviations de 3 lettres me semble bien pire que d’utiliser le nom de la colonne id. (Exemple: qui abrégerait le nom de la table carsavec l'abréviation car? À quoi sert-il?)

Le point est: soyez cohérent. Si votre entreprise utilise Id et que vous commettez souvent l'erreur ci-dessus, prenez l'habitude d'utiliser des noms de table complets. Si votre entreprise bannit la colonne Id, prenez-la au pas et utilisez la convention de dénomination de votre choix.

Concentrez-vous sur l'apprentissage de choses qui sont réellement de mauvaises pratiques (telles que plusieurs sous-requêtes corrélées imbriquées) plutôt que de réfléchir à des problèmes comme celui-ci. La question de nommer vos colonnes "ID" est plus une question de goût que de mauvaise pratique.


A NOTE AUX ÉDITEURS: L'erreur dans cette requête est intentionnelle et est utilisée pour faire valoir un point. Veuillez lire la réponse complète avant de la modifier.


1
@Chad, c'était une référence au fait que dans cette requête, vous utilisiez 3 lettres pour les alias des noms de table, même si cela n'avait aucun sens ( cars-> car. Dieu merci, vous m'avez sauvé les doigts). Ne lisez pas trop profondément dedans.
Riwalk

3
pire que mes pseudonymes, était mon mélange de pluralité carset manufacturer. L'un est pluriel, l'autre non. Si les gens veulent choisir la base de données, c'est la mauvaise pratique à prendre.
CaffGeek

3
Je pense que c'est une mauvaise pratique. Évidemment, en ce qui concerne les mauvaises pratiques, ce n'est pas terrible .. mais c'est si facile à éviter, pourquoi ne pas le faire? Maintenant, je suis d'accord, pour un cours d'intro, est-ce la chose sur laquelle se concentrer? Probablement pas ....
user606723

2
@ user606723, en fait, je pense que pour un cours d'introduction, il est important de faire valoir un point. Enseigner les meilleures pratiques devrait être fondamental. Ce n'est que lorsque vous êtes expérimenté que vous comprenez les conséquences, les compromis et quand vous devez vous écarter des meilleures pratiques.
CaffGeek

5
@Chad, d'accord pour être en désaccord. Essayer d'enseigner aux élèves les "meilleures pratiques" sans leur permettre de comprendre pourquoi ce sont les meilleures est un effort futile. Et comme vous ne pouvez pas tout couvrir, passer sous silence ce point avec "vous ne devriez pas le faire, vous comprendrez pourquoi plus tard" est un choix assez sain d'esprit du point de vue d'un professeur. Les étudiants curieux peuvent écrire ici ou, espérons-le, trouver la réponse à cette question. (Ou demandez après la classe)
user606723

123

Parce que lorsque vous avez une table avec une clé étrangère, vous ne pouvez pas nommer cette clé étrangère "Id". Vous avez table nommez-le TableId

Et puis votre jointure ressemble à

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

Et idéalement, votre condition devrait avoir le même nom de champ de chaque côté.

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Ainsi, bien qu'il semble superflu de nommer l'ID avec ManufacturerId, il est moins probable que vous rencontriez des erreurs dans vos conditions de jointure car elles deviennent évidentes.

Cela semble simple, mais lorsque vous rejoignez plusieurs tables, il est plus probable que vous commettiez une erreur, trouvez celle ci-dessous ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Alors qu'avec un nom correct, l'erreur reste visible ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Une autre raison pour laquelle leur nom est "mauvais", c'est que lorsque vous interrogez des informations sur plusieurs tables, vous devez renommer les colonnes Id afin de pouvoir les distinguer.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Avec des noms précis, c'est moins un problème


174
Pas sûr que ce soit une assez bonne explication pour moi. Il n'y a rien de mal à dire SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. J'ai utilisé idpendant des années et n'ai jamais trouvé ce que vous avez décrit être un réel problème.
Riwalk

61
Je dirais que la mauvaise pratique ici est d'aliaser les tables avec des noms tels que mfg ou mod. Manufacturers.id = cars.manufacturer_id est très lisible et l’erreur persiste.
deadalnix

5
@Chad> J'ai déjà eu des problèmes avec les noms de variables stupides. À plusieurs reprises. Pour l'enregistrement, voici ce que je dirais à un développeur qui le fait dans mon équipe «Mfg ne signifie pas fabricant, cela signifie que vous êtes trop paresseux pour taper fabricant».
deadalnix

9
@ Stargazer712: Faire SELECT * à partir de 2 tables donne 2 colonnes x ID. L'ID est maintenant ambigu: faites-vous référence par ordinal ou par nom? SELECT * n'est pas une bonne pratique non plus. Mauvais arguments. Code fragile. Le Tchad a raison: codage défensif essentiellement
gbn

6
@gbn, encore une fois, toute ambiguïté a disparu si vous le faites tout simplement SELECT manufacturer.id FROM .... Chaque difficulté résultant de idpeut être surmontée très facilement, en faisant simplement une question de goût.
Riwalk

67

La bibliothèque ActiveRecord de Ruby et le GORM de Groovy utilisent "id" par défaut pour la clé de substitution. J'aime cette pratique. La duplication du nom de la table dans chaque nom de colonne est redondante, fastidieuse à écrire et plus fastidieuse à lire.


30
+1 pour "et plus fastidieux à lire." - Les conventions de dénomination ne doivent pas être considérées comme un pansement pour le code bâclé, elles devraient être une préoccupation essentielle pour améliorer la lisibilité.
ocodo

12
ID est beaucoup plus fastidieux à lire
HLGEM

5
@HLGEM: On peut toujours qualifier le nom de la colonne avec le nom de la table.
kevin cline

2
Je suis d'accord sauf pour les plus fastidieux à lire. En fait, je préfère lire des noms de colonne plus descriptifs et moins de temps pour déterminer l’utilité de cette colonne.
Devin Dixon

2
+1, je déteste voir des tables avec des colonnes telles que Posts.postID, Posts.postName où simplement utiliser post.id et post.name est beaucoup plus joli.
Doug

40

Les noms de colonne communs ou clés, tels que "Nom" ou "Id", doivent être précédés du nom TableName.

Cela supprime les ambiguïtés, facilite la recherche, signifie beaucoup moins d'alias de colonnes lorsque les deux valeurs "Id" sont nécessaires.

Une colonne moins utilisée, une colonne d'audit ou une clé (par exemple, LastUpdatedDateTime) n'a pas d'importance


57
Si vous faites cela, je vous hais pour m'avoir fait faire la dactylographie supplémentaire !!!! Le nom de la table est Person, que pensez-vous que l'identifiant va être? Voiture? non, c'est la personne.
Jim

16
@ Jim, je ne sais pas pour vous, mais taper 6 caractères supplémentaires me prend environ une demi-seconde. Et compte tenu du fait que je sélectionne rarement une seule table et que je finirais donc avec deux colonnes nommées "Id" et que je devrais inclure le nom de la table / alias de toute façon, le nombre de caractères saisis ne sera pas réduit.
CaffGeek

21
@Chad je le trouve superflu. si je fais une jointure, c.id = m.manufacturerid, ça me va. Ces colonnes sont généralement "associées" à une classe d'une certaine manière, et avoir une classe avec Person.PersonId me donne envie de vomir ... Oui, je suis pleinement conscient du fait que j'ai des problèmes.
Jim

20
Je suis également en désaccord avec cela. Pourquoi s'arrêter à nameet id? Pourquoi ne pas avoir chaque colonne préfixée avec son nom de table? Il semble arbitraire de choisir ces deux noms pour imposer un préfixe. Conceptuellement, vous devez avoir la table pour avoir le contexte d'une colonne de toute façon. Pourquoi ne pas simplement utiliser ce nom de table pour clarifier la requête: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@ Bill Leeper, DRY n'est pas toujours approprié pour le développement de bases de données. Dans les bases de données, ce qui est important, ce sont les performances et le fait de faire en sorte que la base de données remplisse pleinement les principes de DRY (comme utiliser des fonctions scalaires ou des vues appelant des vues ou des requêtes renvoyant trop de colonnes ou utilisant un curseur pour ajouter des enregistrements 1000000 à utiliser un processus existant). est souvent contre-indiqué. Ne pensez pas que ce n'est que parce que quelque chose de bien dans le monde orienté objet est approprié dans la conception de base de données. Votre vote négatif était inapproprié. Utiliser ID est un anti-modèle SQL connu.
HLGEM

31

Ce fil est mort, mais je voudrais ajouter que l'OMI ne pas utiliser Idest une mauvaise pratique. La Idcolonne est spéciale; c'est la clé primaire. Toute table peut avoir un nombre quelconque de clés étrangères, mais elle ne peut avoir qu'une seule clé primaire. Dans une base de données où toutes les clés primaires sont appelées Id, dès que vous consultez la table, vous savez exactement quelle colonne est la clé primaire.

Croyez-moi, cela fait des mois que je travaille toute la journée dans de nombreuses grosses bases de données (Salesforce) et la meilleure chose que je puisse dire au sujet des schémas est que chaque table a une clé primaire appelée Id. Je peux vous assurer que je ne suis absolument jamais dérouté de joindre une clé primaire à une clé étrangère, car le PK est appelé Id. Une autre chose que les gens n’ont pas mentionnée, c’est que les tables peuvent avoir de longs noms stupides comme Table_ThatDoesGood_stuff__c: ce nom est déjà assez grave car l'architecte a eu la gueule de bois le matin au cours de laquelle il a imaginé cette table, mais vous me dites maintenant que c'est une mauvaise pratique de ne pas appeler la clé primaire Table_ThatDoesGood_stuff__cId (rappelez-vous que les noms de colonnes SQL ne sont généralement pas sensibles à la casse).

Pour être honnête, le problème avec la plupart des enseignants de programmation informatique est qu’ils n’ont pas écrit de ligne de code de production depuis des années, voire jamais, et qu’ils n’ont aucune idée de ce que fait réellement un ingénieur en logiciel. Attendez de commencer à travailler et décidez ensuite ce que vous pensez être une bonne idée ou non.


2
Ce n'est le cas que si aucune de vos clés primaires n'est une clé composite, ce qui est malheureusement trop souvent le cas. On ne devrait vraiment utiliser les clés de substitution que dans des circonstances particulières.
nicodemus13

6
En utilisant Id comme cela, vous vous retrouvez dans une situation où, sans réfléchir, les développeurs ajoutent un identifiant de clé primaire à chacune des tables qu'ils créent. L’un des fondements des bases de données relationnelles est l’utilisation des clés primaires significatives et agrégées; l’utilisation d’id n’aide en rien.
Pieter B

Cette réponse semble juste dire que vous dites "je préfère Id" avec des arguments motivés. Votre argument est que vous pouvez voir instantanément quelle clé est la clé primaire en trouvant celle appelée Id. Eh bien, c'est exactement la même chose avec tableId . Je peux vous garantir que je ne suis jamais confus quelle clé est la clé primaire. Je cherche juste celui qui a le nom de la table avant l'id. Non seulement cela, mais avec quel type de tables païennes travaillez-vous alors que la première colonne n'est pas la clé primaire? Je pense que tous vos arguments dans cette réponse sont purement préférentiels et s'apparentent à "tableId se sent mal pour moi".
dallin

@dallin toutes les réponses sont expliquées, sinon quelqu'un lierait simplement à la norme officielle, et il n'y en a pas!
James le

@ James Je pense que l'objectif des sites StackExchange est de réduire les réponses exprimées en opinions. C'est pourquoi les questions sont fermées car trop d'opinions. Certes, je pense que c’est un peu la raison pour laquelle cette question a été close - parce qu’elle suscite des réponses d’opinions, mais j’ai le sentiment que cette réponse spécifique était trop exagérée sans véritables faits ou arguments étayés par des faits. Toute la réponse peut être résumée en disant: A mon avis, vous devriez utiliser Id, simplement parce que c'est ce que j'aime ". Ce n'est pas une réponse valable.
dallin

24

Je ne considère pas cela comme une mauvaise pratique. La cohérence est roi, comme d'habitude.

Je pense que tout est une question de contexte. Dans le contexte de la table seule, "id" signifie simplement ce que vous attendez, une étiquette permettant de l'identifier de manière unique par rapport à d'autres qui pourraient sinon être (ou paraître) identiques.

Dans le contexte des jointures, il vous incombe de les construire de manière à les rendre lisibles pour vous et votre équipe. Tout comme il est possible de rendre les choses difficiles avec une formulation ou un nom médiocres, il est également possible de construire une requête significative avec une utilisation efficace des alias et même des commentaires.

De la même manière, une classe Java appelée 'Foo' n'a pas ses propriétés préfixées par 'Foo', ne vous sentez pas obligée de préfixer vos ID de table avec des noms de table. En général, la définition de l'ID mentionné est claire dans son contexte .


5
Les tables de base de données relationnelles ne sont pas des classes .
Adam Robinson

1
Ce sont cependant des structures de données et elles sont analogues aux classes PODO. Les mêmes problèmes de nommage s'appliquent.
ocodo

4
@ Slomojo: Non, ils ne sont pas analogues à des objets simples. La conception orientée objet et la conception de la base de données ne sont pas identiques et ne sont même pas liées. Bien qu'ils puissent, dans certains cas, donner une conception similaire (ou même identique), cela n'indique pas qu'ils sont liés. Par exemple, les relations m: m sont triviales dans les classes, mais sont impossibles entre deux tables sans une troisième table d'association.
Adam Robinson

1
Je ne sais pas comment cela se rapporte à une stratégie de nommage. Mon analogie est (clairement?) Seulement étendue à cette mesure.
ocodo

2
Je suis désolé que mon sens implicite n'était pas très clair, j'aurais dû dire " dans ce sens, ils sont analogues à des classes". Quoi qu'il en soit, je ne pense pas que le fait d'être trop pédant à ce sujet soit particulièrement constructif. En termes de nommage, les tables et les classes partagent un grand nombre de similitudes. Les meilleures pratiques développées dans un cul-de-sac sont un jeu passionnant à réviser, ou du moins, peuvent être discutées. Il y a beaucoup de choses dans ce Q & R qui illustrent cela de manière efficace, je n'ai rien d'autre à noter.
ocodo

24

De data.stackexchange.com

Identifiant dans les messages

BOOM, réponse à la question.
Maintenant, allez dire à votre enseignant que vous devez utiliser SO pour créer de mauvaises bases de données.


8
Je pense au FKs, sur la base des noms: PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Pourquoi une pratique aussi facile devrait-elle être considérée comme «mauvaise»?
Sjoerd

3
En quoi cela prouve-t-il exactement les meilleures pratiques?
GBa

5
Que quelque chose soit utilisé ou non en pile ne prouve pas si c'est une bonne ou une mauvaise pratique.
Pieter B

2
Cela prouve bien que cette pratique n'empêche nullement l'évolutivité et l'utilité d'une application.
Cypher

1
En réalité, la pratique n'est pas parfaite. Je voudrais utiliser cette dénomination: PostType -> PostType.Id; AcceptedAnswer -> Answer.Id; OwnerUser -> User.Id
alpav

17

Cela rend difficile (et déroutant) d’effectuer une jointure naturelle sur la table, donc oui, c’est mauvais sinon très mauvais.

Natural Join est un ancien artefact de SQL Lore (c’est-à-dire une algèbre relationnelle) que vous avez peut-être déjà vu: dans un livre de base de données peut-être. Ce que je veux dire, c'est que Natrual Join n'est pas une nouvelle idée SQL sophistiquée, même s'il a semblé que SGBDM avait mis longtemps à l'implémenter. Par conséquent, il ne s'agit pas d'une nouvelle idée fantaisiste à mettre en œuvre, il peut même être déraisonnable de l'ignorer. son existence de nos jours.

Eh bien, si vous nommez tous les ID de votre clé primaire, vous perdez la facilité et la simplicité de la jointure naturelle. select * from dudes natural join carsdevra être écrit select * from dudes inner join cars where cars.dudeid = dudes.idou select * from dudes inner join cars where dudes.carid = cars.id. Si vous êtes capable de faire une jointure naturelle, vous pouvez ignorer ce qu'est réellement la relation, ce qui, à mon avis, est assez impressionnant.


À moins que vous n'écriviez une procédure stockée, quelle est la dernière fois que vous développez une application en tant que développeur d'applications, avez-vous écrit un sélecteur SQL entièrement formaté? Les langues modernes incluent toutes une sorte de fonctionnalité ORM qui gère cette relation pour vous. Le nom de la colonne est beaucoup plus important que de pouvoir écrire du SQL manuel propre.
Bill Leeper

4
@ Bill Je fais tout le temps, plusieurs fois par jour, dépend plus de votre base de code que de la langue que vous développez. Et, pour les diagnostics, si vous souhaitez établir des relations bonnes et profondes, vous pouvez enchaîner ces jointures naturelles et éviter de rechercher des identifiants de champ. Et, comme l'a dit saint Jérôme, "Ignorer les bases de données, c'est ignorer les bases de données".
Peter Turner

Outre le fait que les jointures naturelles ne sont pas universellement prises en charge, les jointures naturelles sont plus difficiles à lire. Y a-t-il deux colonnes en relation ou une seule? Mieux vaut être explicite et éviter les jointures naturelles.
Thomas

1
@Thomas, je ne mettrais pas non plus de jointures naturelles dans le code, mais pour les diagnostics, je les ai trouvées plutôt utiles lorsque la base de données est modélisée pour qu'elles fonctionnent réellement.
Peter Turner

16

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

Par exemple, si vous avez fooTableavec colonne fooTableIdet barTableavec clé étrangère fooTableId, alors vos requêtes peuvent être construites de la manière suivante:

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

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

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

C'est la réponse qui ressort le plus pour moi. Le USINGmot-clé est supporté par la base de données postgres / mysql / sqlite, ce qui signifie moins de dactylographie, raison pour laquelle certaines des autres réponses sont utilisées id, et enfin, à mon avis subjectif, elle est plus lisible.
Michael Barton

11

Pourquoi ne pas demander à votre professeur?

Pensez-y, lorsque toutes les colonnes PK de vos tables sont nommées, IDleur utilisation en tant que clé étrangère devient un cauchemar.

Les noms de colonne doivent être sémantiquement significatifs. IDest générique.


8
trop générique pour quoi? l'identifiant d'une table?
Jim

3
@Jim de quelle table? idseul ne veut rien dire, surtout dans le contexte d'une clé étrangère vers une autre table. Cela n'a rien à voir classeset tout à voir avec une bonne conception de base de base de données relationnelle fondamentale.

10
Pour être légèrement idiot, la table à laquelle il appartient. table.idest un moyen parfaitement acceptable de se référer à un idchamp. Le préfixage du nom du champ avec le nom de la table est redondant.
ocodo

2
@ Slomoj n'est pas plus typé qu'inclure le nom dans la colonne et plus explicite lorsque les noms de table sont aliasés en abréviations à une ou deux lettres dans les jointures de monstres.

6
De quel cauchemar parles-tu? Supposons que vous disposiez d'une structure d'auto-référencement d'employés avec une colonne représentant leur responsable. Comment appelez-vous la clé étrangère? Vous ne pouvez pas l'appeler EmployeeId car il s'agit probablement de votre PK. Le nom du FK ne doit pas nécessairement correspondre au PK. Il doit être nommé pour ce qu'il représente pour l'entité dans laquelle il est contenu.
Thomas

7

L'ID est mauvais pour les raisons suivantes:

Si vous faites beaucoup de requêtes de rapport, vous devez toujours aliaser les colonnes si vous voulez voir les deux. Il devient donc une perte de temps lorsque vous pouvez le nommer correctement pour commencer. Ces requêtes complexes sont assez difficiles (j'écris des requêtes pouvant durer des centaines de lignes) sans la charge supplémentaire de travail inutile.

Il est susceptible de provoquer des erreurs de code. Si vous utilisez une base de données qui permet l'utilisation de la jointure naturelle (non pas à mon avis, mais lorsque des fonctionnalités sont disponibles, quelqu'un les utilisera), vous rejoindrez la mauvaise chose si vous avez un développeur qui l'utilise.

Si vous copiez des jointures pour créer une requête complexe, il est facile d'oublier de changer l'alias pour celui que vous voulez et d'obtenir une jointure incorrecte. Si chaque identifiant est nommé d'après la table dans laquelle il se trouve, vous obtiendrez généralement une erreur de syntaxe. Il est également plus facile de détecter si la jointure dans une requête complexe est incorrecte si le nom pPK et le nom FK correspondent.


+1: Ce sont des raisons impérieuses à mon avis, alors que les autres réponses opposées IDne me convainc pas du tout.
Phoog

Re: "Si vous copiez des jointures pour créer une requête complexe", votre problème est donc de copier-coller. Arrêtez copier / coller et vous verrez à quel point le nommage car.id est pratique. Pour vous joindre à FK, utilisez car.mfg = mfg.id, car.color = color.id, car.model = model.id - très simple et correspond à ce que vous écririez dans LINQ.
alpav

Essayez d’écrire quelque chose avec 30 jointures et vous verrez pourquoi c’est un anti-modèle.
HLGEM

L'aliasing est la raison première et principale - c'est un casse-tête si vous faites de gros rapports complexes. Les jointures naturelles sont juste un bonus doux. C'est incroyable de voir comment les autres réponses ignorent ces points. Je pense que l'ajout de quelques exemples rendrait le point plus clair et ferait passer la réponse plus haut là où elle devrait être.
Lulu

5

Certaines réponses abordent ce que je considère comme la raison la plus importante de ne pas utiliser "id" comme nom de colonne pour la clé primaire dans une table: à savoir la cohérence et l'ambiguïté réduite.

Cependant, pour moi, le principal avantage est le programmeur de maintenance, en particulier celui qui n’a pas participé au développement initial. Si vous utilisez le nom "PersonID" pour l'ID dans la table Person et que vous l'utilisez systématiquement comme clé étrangère, il est simple d'écrire une requête sur le schéma pour savoir quelles tables ont un identifiant PersonID sans avoir à en déduire que "PersonID" est le nom utilisé lorsqu'il s'agit d'une clé étrangère. N'oubliez pas, à tort ou à raison, les relations de clé étrangère ne sont pas toujours appliquées dans tous les projets.

Il existe un cas limite dans lequel une table peut avoir deux clés étrangères dans la même table, mais dans ce cas, je mettrais le nom de la clé d'origine comme nom de suffixe pour la colonne, de sorte qu'une correspondance avec un caractère générique,% PersonID, pourrait facilement être trouvée. ces cas aussi.

Oui, une grande partie de ceci pourrait être accompli avec un standard de "id" et sachant de toujours l'utiliser comme "nomTable", mais cela nécessite à la fois de savoir que la pratique est en place et de laisser les développeurs originaux suivre avec un résultat inférieur. pratique standard intuitive.

Bien que certaines personnes aient fait remarquer qu'il fallait quelques touches supplémentaires pour écrire les noms de colonne les plus longs, je dirais que l'écriture du code ne représente qu'une petite fraction de la vie active du programme. Si l'objectif était de sauver les frappes du développeur, les commentaires ne devraient jamais être écrits.

En tant que personne qui a passé de nombreuses années à gérer de grands projets avec des centaines de tables, je préférerais fortement des noms cohérents pour une clé de table.


Supposons qu'une Companiestable a 2 clés étrangères à une Personstable. L'un représente le président de l'entreprise; l'autre représente le trésorier de l'entreprise. Souhaitez-vous vraiment appeler les colonnes PersonID1et PersonID2? Il serait beaucoup plus descriptif de les appeler PresidentIDet TreasurerID. Je trouve qu'il est beaucoup plus facile de lire inner join Person AS Presidents ON Company.PresidentID = Presidents.IDqueinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
Non. Dans votre exemple, j'aurais probablement une table CompanyOfficerou CompanyPersonqui permet une relation plusieurs à plusieurs entre Companyet Personavec des informations supplémentaires sur la nature de la relation. Si je devais l'implémenter dans la Companytable, j'utiliserais les noms de colonne PresidentPersonIDet TreasurerPersonIDconserverais la partie * PersonID du nom tout en ajoutant le descripteur supplémentaire. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachie

5

La pratique consistant à utiliser Id en tant que champ de clé primaire mène à la pratique dans laquelle id est ajouté à chaque table. Un grand nombre de tables ont déjà des informations uniques qui identifient de manière unique un enregistrement. Utilisez That comme clé primaire et non comme un champ d’identification que vous ajoutez à chaque table. C'est l'un des fondements des bases de données relationnelles.

Et c’est pourquoi l’utilisation d’id est une mauvaise pratique: id n’est souvent pas une information, mais un accroissement automatique.

considérez les tableaux suivants:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Ce qui ne va pas dans ce tableau, c'est qu'il permet à l'utilisateur d'ajouter une autre ligne: États-Unis, avec le code de pays 840. Cela vient de rompre l'intégrité relationnelle. Bien sûr, vous pouvez imposer l'unicité des colonnes individuelles ou simplement utiliser une clé primaire déjà disponible:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

De cette façon, vous utilisez les informations que vous avez déjà en tant que clé primaire, ce qui est au cœur de la conception de bases de données relationnelles.


1
Vous comprendrez pourquoi les utilisateurs ajoutent une colonne de clé générique à chaque table lorsque vous devez migrer des bases de données entre différents systèmes ou avoir eu le plaisir de les fusionner.
Cypher

1
C'est parfois le cas, mais d'après mon expérience, il est assez rare d'avoir une belle clé unique et immuable. Mais même dans votre exemple, vous avez un numéro unique sans signification pour identifier les pays, juste un numéro attribué par l'ISO, pas par votre base de données.
CodesInChaos

Et maintenant, lorsque le nom du pays change, vous devez le mettre à jour dans l'ensemble de votre base de données pour le corriger. Si vous aviez simplement utilisé une clé de substitution (comme ... "id"), la mise à jour serait triviale. Les clés naturelles sont formidables - lorsqu'elles sont complètement immuables et ne changent jamais. En réalité, il existe très peu de cas où cela est vrai.
Gerrat

@Gerrat: Si le nom d'un pays change, le code numérique ISO 3166-1 reste identique, seuls les codes ISO 3166-1 alpha-2 et alpha-3 changent. Cela s'est produit avec la Birmanie / le Myanmar, par exemple. De même, si un pays change de territoire mais conserve son nom, le code numérique ISO 3166-1 change, mais les codes alpha-2 et alpha-3 de l'ISO 3166-1 sont conservés. Cela s'est produit lorsque le Sud-Soudan s'est séparé du Soudan et que l'Érythrée s'est séparée de l'Éthiopie. Lorsque l'Allemagne de l'Est et de l'Ouest se sont réunies, elles ont conservé les codes alpha-2 et alpha-3 de l'Allemagne de l'ouest, mais ont obtenu un nouveau code numérique. Quand les pays se dissolvent ou se transforment complètement (pensez…
Jörg W Mittag

… Issue des guerres des Balkans des années 90), ils obtiennent à la fois de nouveaux codes numériques et alpha-2 et alpha-3.
Jörg W Mittag Le

4

J'utilise toujours 'id' comme nom de colonne principal pour chaque table simplement parce que c'est la convention des frameworks que j'utilise (Ruby on Rails, CakePHP), je n'ai donc pas à le redéfinir tout le temps.

Cela ne battra pas les raisons académiques pour moi.


2

Je ne pense pas que ce soit une mauvaise pratique si elle est utilisée correctement. Il est courant d'avoir un champ ID auto-incrémenté appelé "ID" que vous ne devez jamais toucher et d'utiliser un identifiant plus convivial pour l'application. Écrire du code peut être un peu lourd, from tableA a inner join tableB b on a.id = b.a_idmais ce code peut être caché.

En tant que préférence personnelle, j'ai tendance à préfixer l'identifiant avec le nom de l'entité, mais je ne vois pas de réel problème à utiliser simplement Idsi elle est entièrement gérée par la base de données.


Vous ne rejoindrez jamais deux tables par clé primaire, en particulier un identifiant d'incrémentation automatique. L'exemple ci-dessus serait issu de tableA et d'une jointure interne tableB b sur a.id = b.table_a_id.
Bill Leeper

Oui, c'est ce que je voulais dire. Presque l'heure du déjeuner et besoin d'énergie.
Wayne Molina

2

Les cartes d'identité sont assez communes pour ne pas confondre qui que ce soit. Vous allez toujours vouloir connaître la table. Mettre des noms de champs dans le code de production sans inclure de table / alias est une mauvaise pratique. Si vous êtes trop soucieux de pouvoir taper rapidement des requêtes ad hoc, vous êtes seul.

Espérons que personne ne développe une base de données SQL où ID est un mot réservé.

CREATE TABLE CAR (ID);

Prend soin du nom du champ, de la clé primaire et des incréments automatiques de 1 à partir de 1 tout-en-un joli petit paquet de 2 caractères. Oh, et j'aurais appelé ça CARS mais si nous allons économiser sur les frappes au clavier et qui pense vraiment qu'un tableau appelé CAR va en avoir seulement un?


1
cela montre pourquoi la connaissance de la théorie relationnelle formelle est importante, le nom de la table représente ce qu'est une seule ligne . Le tableau Carreprésente un Tableoù chacun Rowreprésente un simple Car. L'appel en Carschange la sémantique et montre un manque complet de compréhension des principes de base de la théorie relationnelle formelle. Rails est un excellent exemple de quelqu'un qui en savait assez pour être dangereux .

2

Cette question a été battue encore et encore, mais je pensais que j'ajouterais aussi mon opinion.

  1. J'utilise id pour indiquer qu'il s'agit de l'identifiant de chaque table. Ainsi, lorsque je participe à une table et que j'ai besoin de la clé primaire, je me connecte automatiquement à la clé primaire.

  2. Le champ id est un auto-incrémenté, non signé (ce qui signifie que je n'ai jamais à définir sa valeur et que cela ne peut pas être négatif)

  3. Pour les clés étrangères, j'utilise "tablenameid" (là encore une question de style), mais la clé primaire à laquelle je m'associe est le champ id de la table. Par conséquent, la cohérence permet de vérifier les requêtes facilement.

  4. L'identité est courte et douce aussi

  5. Convention supplémentaire - utilisez des minuscules pour tous les noms de table et de colonne, afin qu'aucun problème ne soit détecté en raison de la casse


1

Une autre chose à considérer est que si le nom de la clé primaire est différent du nom de la clé étrangère, il est impossible d'utiliser certains outils tiers.

Par exemple, vous seriez incapable de charger votre schéma dans un outil tel que Visio et de le faire produire des DIR précis.


Ce serait la faute de l'outil tiers cependant. Les conventions de dénomination des colonnes ne remplacent pas les clés étrangères réelles, que l'outil doit introspecter.
Gerrat le

1

Je trouve que les gens ici couvrent à peu près tous les aspects, mais je veux ajouter que "id" n'est pas et ne devrait pas être interprété comme un "identificateur" mais plutôt comme un "index" et qu'il ne définit sûrement pas l'identité de la ligne. (J'ai peut-être utilisé un mauvais libellé ici, corrigez-moi s'il vous plaît)

C'est plus ou moins comment les gens lisent les données de la table et comment ils écrivent leur code. Personnellement, je pense que c’est probablement le moyen le plus populaire, c’est que les codeurs écrivent la référence complète sous la forme table.id, même s’ils n’ont pas besoin de créer des unions ou des jointures. Par exemple:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

De cette façon, vous pouvez le traduire en anglais par "Donne-moi la couleur et le modèle de la voiture numérotée". et non pas comme "Donnez-moi la couleur et le modèle de cette voiture qui est identifiée par le numéro". L'identifiant ne représente en aucun cas la voiture, il ne s'agit que de l'index de la voiture, d'un numéro de série si vous voulez. Juste comme quand vous voulez prendre le troisième élément d'un tableau.

Donc, pour résumer ce que je voulais ajouter, c’est qu’il s’agit simplement d’une question de préférence et que la méthode de lecture SQL décrite est la plus populaire.

Cependant, il existe des cas où cela n'est pas utilisé, tel que (un exemple beaucoup plus rare) où l'ID est une chaîne qui décrit réellement. Par exemple id = "RedFordMustang1970"ou quelque chose de similaire. J'espère vraiment pouvoir expliquer cela au moins pour avoir l'idée.

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.