Quelle est la meilleure pratique pour les clés primaires dans les tables?


256

Lors de la conception des tables, j'ai pris l'habitude d'avoir une colonne unique et que je crée la clé primaire. Ceci est réalisé de trois manières en fonction des besoins:

  1. Colonne entière d'identité qui s'incrémente automatiquement.
  2. Identifiant unique (GUID)
  3. Une colonne de caractère court (x) ou d'entier (ou tout autre type numérique relativement petit) qui peut servir de colonne d'identifiant de ligne

Le numéro 3 serait utilisé pour une recherche assez petite, principalement des tables de lecture qui pourraient avoir un code de chaîne de longueur statique unique ou une valeur numérique telle qu'une année ou un autre nombre.

Pour la plupart, toutes les autres tables auront soit un entier à incrémentation automatique, soit une clé primaire à identifiant unique.

La question :-)

J'ai récemment commencé à travailler avec des bases de données qui n'ont pas d'identifiant de ligne cohérent et les clés primaires sont actuellement regroupées sur différentes colonnes. Quelques exemples:

  • date / caractère
  • date / entier
  • datetime / varchar
  • char / nvarchar / nvarchar

Y a-t-il un cas valable pour cela? J'aurais toujours défini une colonne d'identité ou d'identifiant unique pour ces cas.

De plus, il existe de nombreuses tables sans clé primaire. Quelles sont les raisons valables, le cas échéant, à cela?

J'essaie de comprendre pourquoi les tables ont été conçues telles qu'elles étaient, et cela semble être un gros gâchis pour moi, mais il y avait peut-être de bonnes raisons à cela.

Une troisième question pour m'aider à déchiffrer les réponses: dans les cas où plusieurs colonnes sont utilisées pour comprendre la clé primaire composée, y a-t-il un avantage spécifique à cette méthode par rapport à une clé de substitution / artificielle? Je pense principalement à la performance, à la maintenance, à l'administration, etc.?


J'ai trouvé que les compétences de base de données: une approche saine pour choisir les clés primaires étaient une bonne lecture et je suis la plupart des points soulignés.
user2864740

Réponses:


254

Je respecte quelques règles:

  1. Les clés primaires doivent être aussi petites que nécessaire. Préférez un type numérique car les types numériques sont stockés dans un format beaucoup plus compact que les formats de caractères. En effet, la plupart des clés primaires seront des clés étrangères dans une autre table et utilisées dans plusieurs index. Plus votre clé est petite, plus l'index est petit, moins vous utiliserez de pages dans le cache.
  2. Les clés primaires ne doivent jamais changer. La mise à jour d'une clé primaire devrait toujours être hors de question. En effet, il est plus probable qu'il soit utilisé dans plusieurs index et utilisé comme clé étrangère. La mise à jour d'une seule clé primaire peut provoquer un effet d'entraînement des modifications.
  3. N'utilisez PAS «la clé primaire de votre problème» comme clé primaire du modèle logique. Par exemple, le numéro de passeport, le numéro de sécurité sociale ou le numéro de contrat de l'employé, car ces «clés primaires» peuvent changer pour des situations réelles.

Sur la substitution et la clé naturelle, je me réfère aux règles ci-dessus. Si la clé naturelle est petite et ne changera jamais, elle peut être utilisée comme clé primaire. Si la clé naturelle est grande ou susceptible de changer, j'utilise des clés de substitution. S'il n'y a pas de clé primaire, je crée toujours une clé de substitution, car l'expérience montre que vous ajouterez toujours des tables à votre schéma et que vous souhaitiez mettre une clé primaire en place.


3
Je l'aime! Avez-vous une documentation pour la base de vos "règles"? Merci!
Lloyd Cotten

4
Non, juste l'expérience. Lorsqu'il s'agit de "petites" bases de données, ce genre de choses n'a pas tellement d'importance. Mais quand vous traitez avec de grandes bases de données, toutes les petites choses sont importantes. Imaginez simplement que vous ayez 1 milliard de lignes avec des pk int ou longs par rapport à l'utilisation de texte ou de guid. Il y a une énorme différence!
Logicalmind

44
N'oubliez pas de mettre cet index unique sur la clé naturelle (s'il en existe un, ce qui n'est souvent pas le cas) lorsque vous utilisez une clé artificielle.
HLGEM

3
@Lloyd Cotten: Voici ce qu'un fournisseur de moteur de Big Data dit à l'appui de la règle numéro 1: skyfoundry.com/forum/topic/24 . Cela m'a convaincu de revenir à la Int
table de cuisson

4
même si vous "savez" que "la clé naturelle est petite et ne changera jamais", réfléchissez-y à deux fois. "nous ne réutilisons jamais ces codes" sont les derniers mots célèbres ... A propos des seules choses qui entrent dans les catégories de petites normes sans changement sont les normes iso et autres (codes de pays, codes d'aéroport iata,). Des choses comme "quelle est la représentation en 2 lettres pour cette marque interne" ... réfléchissez-y à deux fois avant de supposer que "ça" ne changera jamais, vous êtes à une décision financière loin d'une reconstruction de base de données.
Andrew Hill

90

Les clés artificielles de vers naturels sont une sorte de débat religieux au sein de la communauté des bases de données - voir cet article et les autres auxquels il renvoie. Je ne suis ni en faveur de toujours avoir des clés artificielles, ni de ne jamais les avoir. Je déciderais au cas par cas, par exemple:

  • États américains: je choisirais state_code ('TX' pour le Texas, etc.), plutôt que state_id = 1 pour le Texas
  • Employés: Je créais généralement un employé_id artificiel, car il est difficile de trouver autre chose qui fonctionne. Le SSN ou l'équivalent peut fonctionner, mais il pourrait y avoir des problèmes comme un nouveau membre qui n'a pas encore fourni son SSN.
  • Historique des salaires des employés: (employee_id, start_date). Je ne créerais pas un id_employé_historique_salaire artificiel. À quel point cela servirait-il (autre que «cohérence insensée» )

Partout où des clés artificielles sont utilisées, vous devez également toujours déclarer des contraintes uniques sur les clés naturelles. Par exemple, utilisez state_id si vous le devez, mais vous feriez mieux de déclarer une contrainte unique sur state_code, sinon vous êtes sûr de finir avec:

state_id    state_code   state_name
137         TX           Texas
...         ...          ...
249         TX           Texas

9
Dans certains cas, avec SQL Server 2005/2008, la clé naturelle (texte) peut être plus rapide qu'une clé int. J'ai une application avec un code convivial de 7 à 8 caractères que nous utilisons comme clé primaire et qui était plus rapide (et souvent plus pratique) qu'un substitut int. Nous avions besoin du code de toute façon afin d'avoir un code lisible / mémorable humain que nous pourrions transférer en toute sécurité sans conflit vers une autre instance d'application (plusieurs sites qui s'agrègent en un site plus grand).
lambacck

1
+1 Bonne réponse. Cependant, je ferais en sorte que l'agent du personnel soit la source fiable d'un identifiant d'employé, c'est-à-dire l'agent responsable de la vérification des employés dans la vie réelle qui sont susceptibles d'utiliser des identifiants tels que SSN, de prendre des références, etc. Le service du personnel doit être digne de confiance source d'identifiants des employés, pas le SGBD!
onedaywhen

@ onedaywhen- je ne voudrais pas. faites confiance à l'officier du personnel. Les gens partent, de nouveaux viennent et ont des idées différentes. Donnez-leur accès à l'identifiant qu'ils pensent être unique / qu'ils veulent utiliser, mais en interne pour la base de données, dba devrait prendre sa propre décision
Dave Pile

1
Notez que le SSN n'est pas nécessairement unique dans tous les pays. Au moins en Autriche, plusieurs personnes pourraient partager le même nombre
maja

Dans certains pays (je pense même aux États-Unis), ils recommandent en fait de ne pas partager le SSN.
Stijn de Witt

25

Juste un commentaire supplémentaire sur quelque chose qui est souvent négligé. Parfois, ne pas utiliser de clé de substitution présente des avantages dans les tables enfants. Disons que nous avons une conception qui vous permet d'exécuter plusieurs sociétés au sein d'une même base de données (c'est peut-être une solution hébergée, ou autre).

Disons que nous avons ces tables et colonnes:

Company:
  CompanyId   (primary key)

CostCenter:
  CompanyId   (primary key, foreign key to Company)
  CostCentre  (primary key)

CostElement
  CompanyId   (primary key, foreign key to Company)
  CostElement (primary key)

Invoice:
  InvoiceId    (primary key)
  CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
  CostCentre   (in foreign key to CostCentre)
  CostElement  (in foreign key to CostElement)

Si ce dernier bit n'a pas de sens, il Invoice.CompanyIdfait partie de deux clés étrangères, l'une vers la table CostCentre et l'autre vers la table CostElement . La clé primaire est ( InvoiceId , CompanyId ).

Dans ce modèle, il n'est pas possible de visser et de référencer un CostElement d'une entreprise et un CostCentre d'une autre entreprise. Si une clé de substitution était utilisée sur les tables CostElement et CostCentre , elle le serait.

Le moins de chances de bousiller, mieux c'est.


6
Il s'agit d'un inconvénient sous-cité lors de l'utilisation de clés de substitution. Si la table a une clé de substitution, je peux toujours l'utiliser pour ce type de contraintes. Malheureusement, bien que la contrainte nécessite un index et il est juste étrange de créer un index unique sur (surrogate_key, other_column) lorsque (surrogate_key) est unique en soi. De plus, (other_column) est souvent totalement redondant dans une table de mappage puisque (surrogate_key) est unique dans la table étrangère. Les mères porteuses peuvent vraiment faire bouger les choses.
Samuel Danielson

24

J'évite d'utiliser des clés naturelles pour une raison simple: l'erreur humaine. Bien que les identifiants uniques naturels soient souvent disponibles (SSN, VIN, numéro de compte, etc.), ils nécessitent qu'un humain les saisisse correctement. Si vous utilisez des SSN comme clé primaire, quelqu'un transpose quelques chiffres lors de la saisie de données et que l'erreur n'est pas découverte immédiatement, vous devez alors changer votre clé primaire.

Mes clés primaires sont toutes gérées par le programme de base de données en arrière-plan et l'utilisateur ne les connaît jamais.


1
J'ai travaillé avec quelques bases de données qui utilisaient des SSN ou des identifiants fiscaux comme clés primaires. Inefficace en matière de stockage et de références de clés étrangères. Sans oublier que le SSN d'une personne peut changer. Je suis donc tout à fait d'accord avec vous.
Alex Jorgenson

13

Il n'y a aucun problème à créer votre clé primaire à partir de divers domaines, c'est une clé naturelle .

Vous pouvez utiliser une colonne d'identité (associée à un index unique sur les champs candidats) pour créer une clé de substitution .

C’est une vieille discussion. Je préfère les clés de substitution dans la plupart des situations.

Mais il n’ya aucune excuse pour l’absence de clé.

RE: EDIT

Oui, il y a beaucoup de controverse à ce sujet: D

Je ne vois aucun avantage évident sur les touches naturelles, outre le fait qu'elles sont le choix naturel. Vous penserez toujours dans Name, SocialNumber - ou quelque chose comme ça - au lieu d' idPerson .

Les clés de substitution sont la réponse à certains des problèmes rencontrés par les clés naturelles (propagation des changements par exemple).

Comme vous vous habituez aux mères porteuses, cela semble plus propre et plus facile à gérer.

Mais au final, vous découvrirez que ce n’est qu’une question de goût - ou d’esprit -. Les gens "pensent mieux" avec des clés naturelles, et d'autres non.


13
Les gens "pensent mieux" avec des clés naturelles. Les machines et les bases de données, non.
FDCastel

11

Les tables doivent toujours avoir une clé primaire. Dans le cas contraire, cela aurait dû être un champ AutoIncrement.

Parfois, les gens omettent la clé primaire car ils transfèrent beaucoup de données et cela peut ralentir (selon la base de données) le processus. MAIS, il faut l'ajouter après.

Quelqu'un commente la table des liens , c'est vrai, c'est une exception MAIS les champs devraient être FK pour garder l'intégrité, et dans certains cas, ces champs peuvent aussi être des clés primaires si la duplication dans les liens n'est pas autorisée ... mais à conserver dans un forme simple car l'exception est quelque chose de souvent dans la programmation, la clé primaire doit être présente pour garder l'intégrité de vos données.


Je suis d'accord. Et dans le cas où beaucoup de données doivent être insérées, supprimez la contrainte de clé primaire (ou utilisez INSERT IDENTITY ON dans TSQL) et remettez-la après :)
Andrew Rollings

1
Il y a des exceptions: les tables de liens évidemment
annakata

Autre raison: s'il n'y a pas de clé PK / unique, les navigateurs de table (je veux dire, quelque chose comme Access / SQL Server Management Studio) refuseront de mettre à jour / supprimer une seule ligne avec une ligne dupliquée. Vous devrez écrire SQL pour cela.
Dennis C

Il est assez courant d'omettre un PK d'une table de faits d'entrepôt de données. Dans Oracle, vous pouvez référencer la pseudocolonne ROWID en tant qu'identifiant unique à court terme (c'est-à-dire ne pas la stocker quelque part et s'attendre à ce qu'elle ne change pas)
David Aldridge

9

Outre toutes ces bonnes réponses, je veux juste partager un bon article que je viens de lire, Le grand débat sur la clé primaire .

Pour ne citer que quelques points:

Le développeur doit appliquer quelques règles lors du choix d'une clé primaire pour chaque table:

  • La clé primaire doit identifier de façon unique chaque enregistrement.
  • La valeur de clé primaire d'un enregistrement ne peut pas être nulle.
  • La valeur-clé primaire doit exister lors de la création de l'enregistrement.
  • La clé primaire doit rester stable - vous ne pouvez pas modifier le ou les champs de clé primaire.
  • La clé primaire doit être compacte et contenir le moins d'attributs possible.
  • La valeur de la clé primaire ne peut pas être modifiée.

Les clés naturelles (ont tendance à) enfreindre les règles. Les clés de substitution sont conformes aux règles. (Vous feriez mieux de lire cet article, cela en vaut la peine!)


7

Quelle est la particularité de la clé primaire?

À quoi sert une table dans un schéma? À quoi sert une clé de table? Quelle est la particularité de la clé primaire? Les discussions autour des clés primaires semblent passer à côté du fait que la clé primaire fait partie d'une table et que cette table fait partie d'un schéma. Ce qui est le mieux pour la table et les relations entre les tables doit conduire la clé utilisée.

Les tableaux (et les relations entre les tableaux) contiennent des faits sur les informations que vous souhaitez enregistrer. Ces faits doivent être autonomes, significatifs, faciles à comprendre et non contradictoires. Du point de vue de la conception, les autres tables ajoutées ou supprimées d'un schéma ne devraient pas avoir d'impact sur la table en question. Il doit y avoir un but pour le stockage des données liées uniquement aux informations elles-mêmes. Comprendre ce qui est stocké dans une table ne devrait pas nécessiter de se soumettre à un projet de recherche scientifique. Aucun fait stocké dans le même but ne doit être stocké plus d'une fois. Les clés sont un ensemble ou une partie des informations enregistrées qui est unique, et la clé primaire est la clé spécialement désignée qui doit être le point d'accès principal à la table (c'est-à-dire qu'elle doit être choisie pour la cohérence et l'utilisation des données, pas seulement pour l'insertion). performance).

  • À part: L'effet secondaire malheureusement de la plupart des bases de données conçues et développées par les programmeurs d'applications (ce que je suis parfois) est que ce qui est le mieux pour l'application ou le cadre d'application entraîne souvent le choix de la clé primaire pour les tables. Cela conduit à des clés entières et GUID (car elles sont simples à utiliser pour les frameworks d'application) et à des conceptions de table monolithiques (car elles réduisent le nombre d'objets de framework d'application nécessaires pour représenter les données en mémoire). Ces décisions de conception de bases de données axées sur les applications entraînent des problèmes importants de cohérence des données lorsqu'elles sont utilisées à grande échelle. Les cadres d'application conçus de cette manière conduisent naturellement à des conceptions de table à la fois. Des «enregistrements partiels» sont créés dans des tableaux et des données remplies au fil du temps. L'interaction multi-tables est évitée ou, lorsqu'elle est utilisée, provoque des données incohérentes lorsque l'application ne fonctionne pas correctement. Ces conceptions conduisent à des données dénuées de sens (ou difficiles à comprendre), des données réparties sur des tables (vous devez regarder d'autres tables pour comprendre la table actuelle) et des données dupliquées.

Il a été dit que les clés primaires devraient être aussi petites que nécessaire. Je dirais que les clés ne doivent être aussi grandes que nécessaire. L'ajout aléatoire de champs dénués de sens à une table doit être évité. Il est encore pire de créer une clé à partir d'un champ vide de sens ajouté au hasard, en particulier lorsqu'il détruit la dépendance de jointure d'une autre table vers la clé non primaire. Cela n'est raisonnable que s'il n'y a pas de bonnes clés candidates dans la table, mais cette occurrence est sûrement le signe d'une mauvaise conception du schéma si elle est utilisée pour toutes les tables.

Il a également été dit que les clés primaires ne devraient jamais changer car la mise à jour d'une clé primaire devrait toujours être hors de question. Mais la mise à jour est la même que la suppression suivie de l'insertion. Selon cette logique, vous ne devez jamais supprimer un enregistrement d'une table avec une clé, puis ajouter un autre enregistrement avec une deuxième clé. L'ajout de la clé primaire de substitution ne supprime pas le fait que l'autre clé de la table existe. La mise à jour d'une clé non primaire d'une table peut détruire la signification des données si d'autres tables dépendent de cette signification via une clé de substitution (par exemple, une table d'état avec une clé de substitution dont la description d'état est passée de «Traité» à «Annulé»). 'corromprait définitivement les données). Ce qui devrait toujours être hors de question, c'est de détruire le sens des données.

Cela dit, je suis reconnaissant pour les nombreuses bases de données mal conçues qui existent dans les entreprises aujourd'hui (mastodontes sans signification-clé de substitution-données corrompues-1NF), car cela signifie qu'il y a une quantité infinie de travail pour les personnes qui comprennent une conception de base de données appropriée. . Mais d'un côté triste, cela me fait parfois me sentir comme Sisyphe, mais je parie qu'il avait un sacré 401k (avant le crash). Éloignez-vous des blogs et des sites Web pour les questions importantes de conception de base de données. Si vous concevez des bases de données, recherchez CJ Date. Vous pouvez également référencer Celko pour SQL Server, mais uniquement si vous tenez le nez en premier. Côté Oracle, référence à Tom Kyte.


1
"Par cette logique, vous ne devez jamais supprimer un enregistrement d'une table avec une clé, puis ajouter un autre enregistrement avec une deuxième clé." - Il y a un cas pour cela, et c'est effectivement ce que fera une clause "ON DELETE RESTRICT" sur une clé étrangère. Dans certains cas (par exemple lorsqu'une piste d'audit est requise), un champ booléen "supprimé" serait préférable à la suppression de l'enregistrement.
Waz

6

Une clé naturelle, si elle est disponible, est généralement la meilleure. Donc, si datetime / char identifie de manière unique la ligne et que les deux parties ont un sens pour la ligne, c'est parfait.

Si juste le datetime est significatif, et que le caractère est juste ajouté pour le rendre unique, alors vous pourriez aussi bien aller avec un champ d'identification.


9
Habituellement mieux? Je n'ai aucune base scientifique, mais je suis presque certain que la plupart des gens préfèrent une clé de substitution au naturel. Dans de nombreux cas, il n'y a pas de clé naturelle.
JC.

3
Il devrait TOUJOURS y avoir une clé naturelle pour n'importe quelle ligne de votre base de données. Cette clé "naturelle" peut être générée par le monde des affaires ou par votre système technique, mais elle doit toujours exister.
Tom H

2
Si, dans votre monde, c'est ce qui a été déterminé comme étant le seul moyen d'identifier une ligne dans le tableau, alors oui. Bien sûr, lorsqu'un concepteur choisit de créer un GUID pour un PK, c'est généralement parce qu'il n'a pas fait le travail pour trouver la vraie clé naturelle, donc dans ce cas, le GUID n'est PAS la clé naturelle.
Tom H

8
2. Si vous prenez votre clé du monde naturel, le monde naturel changera pour casser votre clé. Si vous utilisez le numéro de téléphone, vous obtiendrez deux utilisateurs du même ménage. Si vous utilisez le nom de famille, ils se marient. Si vous utilisez SSN, les lois sur la confidentialité changeront et vous obligeront à les supprimer.
James Orr

2
@Barry: RE: # 2. si le monde naturel change et que votre clé naturelle change, cela signifie que vous avez mal fait de sélectionner une clé naturelle. Par définition, une clé naturelle ne change pas avec le temps.
Tom H

6

Voici ma propre règle de base sur laquelle je me suis installé après plus de 25 ans d'expérience en développement.

  • Toutes les tables doivent avoir une clé primaire à colonne unique qui s'incrémente automatiquement.
  • Incluez-le dans toute vue pouvant être mise à jour
  • La clé primaire ne doit avoir aucune signification dans le contexte de votre application. Cela signifie qu'il ne doit pas s'agir d'une SKU, d'un numéro de compte ou d'un identifiant d'employé ou de toute autre information significative pour votre application. Il s'agit simplement d'une clé unique associée à une entité.

La clé primaire est utilisée par la base de données à des fins d'optimisation et ne doit pas être utilisée par votre application pour autre chose que l'identification d'une entité particulière ou concernant une entité particulière.

Toujours avoir une clé primaire à valeur unique rend l'exécution des UPSERT très simple.

Utilisez des index supplémentaires pour prendre en charge les clés multi-colonnes qui ont un sens dans votre application.


5

Pour moi, les clés naturelles et artificielles dépendent de la quantité de logique métier que vous voulez dans votre base de données. Le numéro de sécurité sociale (SSN) en est un excellent exemple.

"Chaque client de ma base de données aura et doit avoir un SSN." Bam, c'est fait, faites-en la clé primaire et finissez-en. N'oubliez pas que lorsque votre règle d'entreprise change, vous êtes brûlé.

Je n'aime pas moi-même les clés naturelles, en raison de mon expérience de l'évolution des règles métier. Mais si vous êtes sûr que cela ne changera pas, cela pourrait empêcher quelques jointures critiques.


8
Et j'ai vu des données où le SSN n'est pas unique, même s'il devrait l'être. Méfiez-vous des clés naturelles si vous importez vos données d'une autre source!
HLGEM

2
Si vous êtes victime d'un vol d'identité, vous pouvez faire modifier votre numéro de sécurité sociale. Il y a quatre autres situations où ils changeront votre numéro et ils sont répertoriés sur le site ssa.gov.
Zvi Twersky

4

Je soupçonne que la thérapie de journaux enroulée de Steven A. Lowe est nécessaire pour le concepteur de la structure de données d'origine.

En passant, les GUID en tant que clé primaire peuvent être un porc de performance. Je ne le recommanderais pas.


2
Dire que c'est un porc de performance est une optimisation prématurée. Des guides sont requis dans certains cas (clients déconnectés, fusion de table future, réplication)
JC.

2
"Optimisation prématurée" est une expression galvaudée sur SO (IMHO)! Oui, les GUID peuvent être requis dans CERTAINS cas, mais Andrew a raison de souligner qu'ils ne doivent pas être utilisés comme type de données par défaut, qu'ils soient requis ou non.
Tony Andrews

OK, ce n'était en fait pas une optimisation prématurée. Ce que je voulais dire, c'est que la plupart des gens ne connaissent pas le volume requis pour remarquer la différence de performances. Oui, utilisez l'auto-incrémentation si vous savez que vous n'aurez jamais besoin d'un guide.
JC.

Ou utilisez les deux. Avoir une clé primaire basée sur int / long pour de belles sélections et jointures rapides, puis avoir un champ guid. Du moins, c'est ce que je fais. Est-ce mal? Ne devrais-je pas faire ça? :)
Andrew Rollings

J'utilise également les deux colonnes. Mais je ne sais pas si c'est faux ou pas. L'avez-vous trouvé @AndrewRollings?
YÒGÎ

3

Vous devez utiliser une clé primaire «composite» ou «composée» qui comprend plusieurs champs.

Ceci est une solution parfaitement acceptable, allez ici pour plus d'informations :)


3

Moi aussi, j'utilise toujours une colonne d'identification numérique. Dans oracle, j'utilise le nombre (18,0) sans raison réelle au-dessus du nombre (12,0) (ou tout ce qui est un int plutôt qu'un long), peut-être que je ne veux tout simplement pas m'inquiéter d'avoir quelques milliards de lignes dans le db!

J'inclus également une colonne créée et modifiée (type horodatage) pour le suivi de base, où cela semble utile.

Cela ne me dérange pas de configurer des contraintes uniques sur d'autres combinaisons de colonnes, mais j'aime vraiment mon id, les exigences de base créées et modifiées.


2
Je dois également souligner que je ne mets pas d'ID sur les tables de liaison / jointure, uniquement sur les tables contenant des données.
JeeBee

3

Je recherche des clés primaires naturelles et les utilise où je peux.

Si aucune clé naturelle ne peut être trouvée, je préfère un GUID à un INT ++ car SQL Server utilise des arbres, et il est mauvais d'ajouter toujours des clés à la fin dans les arbres.

Sur les tables qui sont des couplages plusieurs-à-plusieurs, j'utilise une clé primaire composée des clés étrangères.

Parce que j'ai la chance d'utiliser SQL Server, je peux étudier les plans d'exécution et les statistiques avec le profileur et l'analyseur de requêtes et découvrir comment mes clés fonctionnent très facilement.


Avez-vous une documentation pour sauvegarder cette déclaration: «si aucune clé naturelle ne peut être trouvée, je préfère un GUID à un INT ++ parce que SQL Server utilise des arbres, et il est mauvais de toujours ajouter des clés à la fin dans les arbres. Pas sceptique, essayant simplement de compiler de la documentation.
Lloyd Cotten

1
@Lloyd - Heureux que vous vous intéressiez à quelque chose que je trouve très fascinant moi-même. Un bon point de départ sur msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx
Guge

2

J'utilise toujours un numéro automatique ou un champ d'identité.

J'ai travaillé pour un client qui avait utilisé SSN comme clé primaire, puis à cause des réglementations HIPAA, j'ai été obligé de passer à un "MemberID" et cela a causé une tonne de problèmes lors de la mise à jour des clés étrangères dans les tables associées. S'en tenir à une norme cohérente d'une colonne d'identité m'a aidé à éviter un problème similaire dans tous mes projets.


6
Une mauvaise sélection d'une clé naturelle par un développeur ne signifie pas que les clés naturelles sont mauvaises.
Tom H

1
Un outil difficile à utiliser n'est pas en quelque sorte un point contre cet outil?
Sqeaky

1

Toutes les tables doivent avoir une clé primaire. Sinon, ce que vous avez est un HEAP - cela, dans certaines situations, pourrait être ce que vous voulez (charge d'insertion lourde lorsque les données sont ensuite répliquées via un courtier de services vers une autre base de données ou table par exemple).

Pour les tables de recherche avec un faible volume de lignes, vous pouvez utiliser un code 3 CHAR comme clé primaire car cela prend moins de place qu'un INT, mais la différence de performances est négligeable. En dehors de cela, j'utiliserais toujours un INT sauf si vous avez une table de référence qui a peut-être une clé primaire composite composée de clés étrangères de tables associées.


1

Si vous voulez vraiment lire tous les allers-retours sur ce débat séculaire, faites une recherche de "clé naturelle" sur Stack Overflow. Vous devriez récupérer des pages de résultats.


1

Les GUID peuvent être utilisés comme clé primaire, mais vous devez créer le bon type de GUID pour qu'il fonctionne bien.

Vous devez générer des GUID COMB. Un bon article à ce sujet et des statistiques de performances est Le coût des GUID en tant que clés primaires .

De plus, du code sur la création de GUID COMB dans SQL se trouve dans Uniqueidentifier vs identity ( archive ) .


5
À mon humble avis, les guides ne doivent être utilisés que lorsque vous devez synchroniser des données entre des bases de données. Dans lequel un identifiant généré automatiquement pose problème. La différence entre l'utilisation d'un guid et l'utilisation d'un type numérique de base est qu'un guid nécessitera 16 octets par ligne, tandis qu'un numérique sera beaucoup plus petit.
Logicalmind

Si vous allez sur le lien que j'ai fourni ci-dessus, il y a très peu de différence de performances avec COMB Guids.
Donny V.

0

Nous faisons beaucoup de jointures et les clés primaires composites viennent de devenir un porc de performance. Un simple int ou long résout de nombreux problèmes même si vous introduisez une deuxième clé candidate, mais il est beaucoup plus facile et plus compréhensible de se joindre à un champ plutôt qu'à trois.


1
Cette stratégie s'effondre lorsque vous devez maintenant parcourir 6 tables pour rejoindre les deux tables dont vous avez besoin car les clés composites n'ont pas été propagées. Cela finit également par nécessiter l'utilisation de boucles / curseurs pour plusieurs inserts qui peuvent être un porc de performance ÉNORME.
Tom H

2
Je ne suis pas trop grand pour apprendre quelque chose de nouveau. J'aimerais voir un exemple de ce que vous dites, il serait utile d'injecter un petit fait rationnel dans certains de ces arguments religieux.
Dan Blair

0

Je serai franc au sujet de ma préférence pour les clés naturelles - utilisez-les lorsque cela est possible, car elles vous faciliteront la vie dans l'administration de la base de données. J'ai établi une norme dans notre entreprise selon laquelle toutes les tables ont les colonnes suivantes:

  • ID de ligne (GUID)
  • Créateur (chaîne; a par défaut le nom de l'utilisateur actuel ( SUSER_SNAME()en T-SQL))
  • Créé (DateTime)
  • Horodatage

L'ID de ligne possède une clé unique par table et, dans tous les cas, est généré automatiquement par ligne (et les autorisations empêchent quiconque de le modifier), et il est raisonnablement garanti qu'il est unique dans toutes les tables et bases de données. Si des systèmes ORM ont besoin d'une seule clé d'identification, c'est celle à utiliser.

Pendant ce temps, le PK réel est, si possible, une clé naturelle. Mes règles internes sont quelque chose comme:

  • Personnes - utilisez la clé de substitution, par exemple INT. S'il est interne, le GUID de l'utilisateur Active Directory est un choix acceptable
  • Tables de recherche (par exemple, StatusCodes) - utilisez un code CHAR court; il est plus facile à retenir que les INT, et dans de nombreux cas, les formulaires papier et les utilisateurs l'utiliseront également pour plus de brièveté (par exemple, Status = "E" pour "Expired", "A" pour "Approved", "NADIS" pour "No Asbestos Detected"). Dans l'exemple ")
  • Tables de liaison - combinaison de FK (par exemple EventId, AttendeeId)

Donc, idéalement, vous vous retrouvez avec un PK naturel, lisible par l'homme et mémorable, et un GUID à ID unique par table ORM.

Attention: les bases de données que je gère tendent vers les 100 000 enregistrements plutôt que des millions ou des milliards, donc si vous avez l'expérience de systèmes plus grands qui contre-indiquent mes conseils, n'hésitez pas à m'ignorer!


1
Suggérez-vous de créer les deux GUID et les INT SK pour les tables sans clé naturelle forte?

Vous n'êtes pas obligé, mais les avantages sont les suivants: a) cela facilite la réplication si vous en avez besoin, b) lorsque vous traitez avec ORM, vous pouvez attribuer un ID unique à votre objet dans le code avant de l'enregistrer (ce qui est utile si vous vous devez faire beaucoup de modifications sur votre objet, peut-être enregistrer dans un cache de session, avant de l'enregistrer). La clé est l'INT dans cette instance; le GUID n'est qu'un bonus.
Keith Williams
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.