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?
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?
Réponses:
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 cars
avec 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.
cars
-> car
. Dieu merci, vous m'avez sauvé les doigts). Ne lisez pas trop profondément dedans.
cars
et manufacturer
. L'un est pluriel, l'autre non. Si les gens veulent choisir la base de données, c'est la mauvaise pratique à prendre.
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
SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId
. J'ai utilisé id
pendant des années et n'ai jamais trouvé ce que vous avez décrit être un réel problème.
SELECT manufacturer.id FROM ...
. Chaque difficulté résultant de id
peut être surmontée très facilement, en faisant simplement une question de goût.
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.
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
name
et 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, ...
Ce fil est mort, mais je voudrais ajouter que l'OMI ne pas utiliser Id
est une mauvaise pratique. La Id
colonne 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.
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 .
BOOM, réponse à la question.
Maintenant, allez dire à votre enseignant que vous devez utiliser SO pour créer de mauvaises bases de données.
PostTypeId -> PostTypes.Id
; AcceptedAnswerId -> Answers.Id
; OwnerUserId -> Users.Id
. Pourquoi une pratique aussi facile devrait-elle être considérée comme «mauvaise»?
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 cars
devra être écrit select * from dudes inner join cars where cars.dudeid = dudes.id
ou 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.
Il existe une situation où coller "ID" sur chaque table n'est pas la meilleure idée: le USING
mot - clé, s'il est pris en charge. Nous l'utilisons souvent dans MySQL.
Par exemple, si vous avez fooTable
avec colonne fooTableId
et barTable
avec 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)
USING
mot-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.
Pourquoi ne pas demander à votre professeur?
Pensez-y, lorsque toutes les colonnes PK de vos tables sont nommées, ID
leur utilisation en tant que clé étrangère devient un cauchemar.
Les noms de colonne doivent être sémantiquement significatifs. ID
est générique.
id
seul ne veut rien dire, surtout dans le contexte d'une clé étrangère vers une autre table. Cela n'a rien à voir classes
et tout à voir avec une bonne conception de base de base de données relationnelle fondamentale.
table.id
est un moyen parfaitement acceptable de se référer à un id
champ. Le préfixage du nom du champ avec le nom de la table est redondant.
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.
ID
ne me convainc pas du tout.
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.
Companies
table a 2 clés étrangères à une Persons
table. 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 PersonID1
et PersonID2
? Il serait beaucoup plus descriptif de les appeler PresidentID
et TreasurerID
. Je trouve qu'il est beaucoup plus facile de lire inner join Person AS Presidents ON Company.PresidentID = Presidents.ID
queinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
CompanyOfficer
ou CompanyPerson
qui permet une relation plusieurs à plusieurs entre Company
et Person
avec des informations supplémentaires sur la nature de la relation. Si je devais l'implémenter dans la Company
table, j'utiliserais les noms de colonne PresidentPersonID
et TreasurerPersonID
conserverais la partie * PersonID du nom tout en ajoutant le descripteur supplémentaire. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
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.
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_id
mais 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 Id
si elle est entièrement gérée par la base de données.
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?
Car
représente un Table
où chacun Row
représente un simple Car
. L'appel en Cars
change 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 .
Cette question a été battue encore et encore, mais je pensais que j'ajouterais aussi mon opinion.
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.
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)
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.
L'identité est courte et douce aussi
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
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.
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.