Comment aimez-vous vos clés primaires? [fermé]


88

Dans une discussion assez animée dans mon équipe, on m'a fait penser à ce que la plupart des gens aiment comme clés primaires. Nous avions les groupes suivants-

  1. Int / BigInt dont l'auto-incrémentation sont des clés primaires assez bonnes.
  2. Il doit y avoir au moins 3 colonnes qui constituent la clé primaire.
  3. L'ID, le GUID et les identificateurs de ligne lisibles par l'homme doivent tous être traités différemment.

Quelle est la meilleure approche pour les PK? Ce serait génial si vous pouviez justifier votre opinion. Y a-t-il une meilleure approche que celle ci-dessus?

EDIT: N'importe qui a un simple exemple / algorithme pour générer des identifiants lisibles par l'homme pour les lignes qui s'adaptent bien?


1
Puisque c'est subjectif, il devrait s'agir d'un wiki communautaire
John Sheehan

2
"Il devrait y avoir au moins 3 colonnes qui composent la clé primaire"? Qu'est-ce que ça veut dire? Pouvez-vous fournir une définition plus détaillée? Ou est-ce que cela fait partie du n ° 3?
S.Lott

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst: Pourquoi est-ce une exigence? Pourquoi doit-il y avoir trois colonnes dans un PK? Pourquoi un ou quatre?
S.Lott

Je pouvais voir un PK à trois colonnes ressemblant à ... LocalID (Auto increment int), GlobalID (GUID), ForeignId (clé étrangère comme RolesType), etc. Le LocalID + ForiegnId pourrait être une combinaison de touches composées. Le Guid est utilisé pour d'autres sites Web / services. Personnellement, je ne ferais pas cela, j'utiliserais simplement Guid + ForiegnId.
Jerad

Réponses:


76

Si vous souhaitez effectuer une synchronisation entre des bases de données avec des applications parfois connectées, vous devez utiliser des GUID pour vos clés primaires. C'est un peu pénible pour le débogage, donc à part ce cas, j'ai tendance à m'en tenir à cet auto-incrémentation.

Les entiers d'auto-incrémentation doivent être votre valeur par défaut, et ne pas les utiliser doit être justifié.


3
Un GUID n'est pas nécessaire, changez simplement l'étape à 10 ou 20 ou quel que soit le nombre de serveurs avec lesquels vous devrez éventuellement vous synchroniser à l'avenir.
Robert C. Barth

43
Au moins 90% du temps, un GUID n'est pas nécessaire et gaspille de l'espace.
Jonathan Leffler

8
Je pense sérieusement que les GUID sont exagérés. Jamais encore eu besoin d'avoir des GUID comme clés primaires.
Cyril Gupta

7
Ou, au lieu de gaspiller de l'espace et de risquer une collision avec un GUID, créez une clé composite de la clé primaire d'origine et un petit identifiant, où le petit identifiant est différent pour chaque source de synchronisation.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
Un magasin pour lequel j'ai travaillé utilisait des GUID pour tout, même lorsque des identifiants publics étaient disponibles, comme les codes ISO de pays ou de langue. Et même quand un booléen ou CHAR(1)aurait suffi, comme pour sex. Inutile de dire que c'était un cauchemar avec lequel travailler.
Lumi

56

Je ne vois pas de réponse qui souligne (ce que je considère comme) le point vraiment fondamental - à savoir, qu'une clé primaire est ce qui garantit que vous n'obtiendrez pas deux entrées dans le tableau pour la même entité du monde réel (comme modélisé dans la base de données). Cette observation permet d'établir ce qui est bon et ce qui est de mauvais choix pour la clé primaire.

Par exemple, dans un tableau de noms et de codes d'état (américains), le nom ou le code peut être la clé primaire - ils constituent deux clés candidates différentes, et l'une d'entre elles (normalement la plus courte - le code) est choisie comme clé clé primaire. Dans la théorie des dépendances fonctionnelles (et des dépendances de jointure - 1NF à 5NF - ce sont les clés candidates qui sont cruciales plutôt qu'une clé primaire.

Pour un contre-exemple, les noms humains font généralement un mauvais choix pour la clé primaire. Il y a beaucoup de gens qui s'appellent "John Smith" ou d'autres noms similaires; même en tenant compte des prénoms (rappelez-vous: tout le monde n'en a pas - par exemple, je n'en ai pas), il y a beaucoup de possibilités de duplication. Par conséquent, les gens n'utilisent pas de noms comme clés primaires. Ils inventent des clés artificielles telles que le numéro de sécurité sociale (SSN) ou le numéro d'employé et les utilisent pour désigner l'individu.

Une clé primaire idéale est courte, unique, mémorable et naturelle. Parmi ces caractéristiques, l'unicité est obligatoire; les autres doivent fléchir compte tenu des contraintes des données du monde réel.

Lorsqu'il s'agit de déterminer la clé primaire d'une table donnée, vous devez donc regarder ce que représente cette table. Quel ensemble ou ensembles de valeurs de colonne dans la table identifie de manière unique chaque ligne de la table? Ce sont les clés candidates. Maintenant, si chaque clé candidate se compose de 4 ou 5 colonnes, vous pouvez décider que celles-ci sont trop maladroites pour constituer une bonne clé primaire (principalement pour des raisons de brièveté). Dans ces circonstances, vous pouvez introduire une clé de substitution - un nombre généré artificiellement. Très souvent (mais pas toujours) un simple entier de 32 bits est suffisant pour la clé de substitution. Désignez ensuite cette clé de substitution comme clé primaire.

Cependant, vous devez toujours vous assurer que les autres clés candidates (car la clé de substitution est également une clé candidate, ainsi que la clé primaire choisie) sont toutes conservées en tant qu'identifiant unique - normalement en plaçant une contrainte unique sur ces ensembles de colonnes.

Parfois, les gens ont du mal à identifier ce qui rend une ligne unique, mais il devrait y avoir quelque chose à faire, car simplement répéter une information ne la rend pas plus vraie. Et si vous ne faites pas attention et que vous obtenez deux (ou plus) lignes censées stocker les mêmes informations, et que vous devez ensuite mettre à jour les informations, il existe un danger (surtout si vous utilisez des curseurs) que vous ne mettiez à jour qu'une seule ligne. plutôt que chaque ligne, de sorte que les lignes ne sont pas synchronisées et personne ne sait quelle ligne contient les informations correctes.

C'est une vision assez dure, à certains égards.

Je n'ai aucun problème particulier avec l'utilisation d'un GUID quand ils sont nécessaires, mais ils ont tendance à être gros (comme dans 16-64 octets), et ils sont utilisés trop souvent. Très souvent, une valeur de 4 octets parfaitement bonne suffit. L'utilisation d'un GUID où une valeur de 4 octets suffirait gaspille de l'espace disque et ralentit même l'accès indexé aux données car il y a moins de valeurs par page d'index, donc l'index sera plus profond et plus de pages devront être lues pour accéder au information.


10
En ce qui concerne votre échantillon avec des noms d'états américains, je préférerais une clé de substitution distincte, simplement parce que les codes sont hors de votre contrôle. S'ils doivent changer pour une raison quelconque, vous avez un problème.
Dirk Vollmar le

(suite) Par exemple, l'Allemagne a remplacé un système de code postal à 4 chiffres par un système à 5 chiffres dans les années 1990 après la réunification.
Dirk Vollmar le

@divo: Je suis un ardent défenseur des clés artificielles / de substitution, mais même je ne vois pas le changement de code postal de 4 à 5 chiffres comme un bon exemple. Les codes postaux ne sont généralement pas utilisés comme clés pour quoi que ce soit. (À quand remonte la dernière fois que vous avez dû interroger une table PostalCode pour trouver quelque chose à propos de ce code? Non, il est presque exclusivement utilisé dans le cadre d'une adresse sans être référencé dans d'autres tables. Je dirais que votre suggestion est presque comparable à l'utilisation clés de substitution pour les adresses elles-mêmes.)
ErikE

@Emtucifor: Oui, peut-être que ZIP n'est pas un exemple très pratique, mais mon argument était que si une partie de votre clé de substitution est hors de votre contrôle et change pour une raison quelconque, vous êtes en difficulté. Pensez à quelqu'un qui crée un nouveau système de numéro de sécurité sociale, un nouveau système ISSN ou - peut-être plus réaliste - une entreprise qui décide de créer un nouveau système d'identification de produit après une fusion, en attribuant de nouveaux numéros d'employés à ses employés pour ajuster leur croissance, etc. tous juste des exemples fictifs, mais, comme mon exemple précédent avec le ZIP le montre, parfois un système bien établi peut changer.
Dirk Vollmar le

2
Votre premier point est correct. Il y a un nom pour cette contrainte. C'est ce qu'on appelle «l'intégrité de l'entité». L'IE exige que chaque entité ait une identité unique. Les clés primaires répondent souvent à cette exigence, sauf lorsque la numérotation automatique est utilisée. Avec la numérotation automatique, vous pouvez obtenir deux lignes identiques, à l'exception de la numérotation automatique. Cela viole généralement l'intégrité de l'entité.
Walter Mitty

26

Ce n'est qu'un problème religieux parce que les gens recherchent une bonne réponse universelle. Le fait que votre équipe et ce fil SO montrent autant de désaccords devrait être un indice qu'il existe de bonnes raisons d'utiliser toutes les solutions que vous décrivez, dans des circonstances différentes.

  • Les clés de substitution sont utiles lorsqu'aucun autre attribut ou ensemble d'attributs de la table ne convient pour identifier les lignes de manière unique.
  • Les clés naturelles sont préférées, lorsque cela est possible, pour rendre le tableau plus lisible par l'homme. Les clés naturelles permettent également à la clé étrangère dans une table dépendante de contenir une valeur réelle au lieu d'un identifiant de substitution. Par exemple, lorsque vous devez stocker state(CA, TX, NY), vous pouvez également utiliser unchar(2) clé naturelle au lieu d'un int.
  • Utilisez des clés primaires composées le cas échéant. N'ajoutez pas de "id inutilement une clé de substitution " lorsqu'une clé composée parfaitement bonne existe (ceci est particulièrement vrai dans les tables plusieurs-à-plusieurs). Un mandat pour une clé à trois colonnes dans chaque table est un non-sens absolu.
  • Les GUID sont une solution lorsque vous devez préserver l'unicité sur plusieurs sites. Ils sont également utiles si vous avez besoin que les valeurs de la clé primaire soient uniques, mais non ordonnées ou consécutives.
  • INT vs BIGINT: il n'est pas courant qu'une table nécessite une plage de 64 bits pour les clés primaires, mais avec la disponibilité croissante du matériel 64 bits, cela ne devrait pas être un fardeau et donne plus d'assurance que vous ne déborderez pas. INT est bien sûr plus petit, donc si l'espace est limité, cela peut donner un léger avantage.

6
Je ne suis pas d'accord autant qu'une personne peut le faire. Les clés naturelles sont horribles. Et si l'on veut changer les données? Oh, tu ne peux pas. L'écriture de jointures sur des clés naturelles composites est une douleur. Porter cette clé composite à toutes vos tables associées est un gaspillage.
Robert C. Barth

2
@Robert: découvrez "ON UPDATE CASCADE". Mais je comprends ce que vous dites et je suis d'accord qu'il est préférable d'utiliser une clé de substitution la plupart du temps, car les attributs sont sujets à changement et ne sont pas uniques.
Bill Karwin

1
Les clés primaires doivent être immuables. Les mises à jour en cascade ne sont qu'un mauvais hack pour une mauvaise décision de conception dans ce cas. Les clés naturelles ne sont JAMAIS préférées. Idem pour les clés composites, qui se propagent comme une peste. Toute personne ayant plus de 3 mois d'expérience dans le développement de bases de données le saurait.
FDCastel

7
@FD: Je ne suis pas d'accord avec votre affirmation sans équivoque, et je développe avec des bases de données SQL depuis 1992. Mais il est certainement vrai que les clés de substitution sont les mieux à même de rester immuables.
Bill Karwin

20

J'aime le blog The Database Programmer en tant que source de ce genre d'informations.

3 colonnes pour une clé primaire? Je dirais que les colonnes devraient avoir des contraintes uniques appropriées comme l'exigent les règles métier, mais j'aurais toujours une clé de substitution distincte. Les clés composées signifient que la logique métier entre dans la clé. Si la logique change, tout votre schéma est vissé.


2
Ils ont changé leur lien, voici le signet mis à jour: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

Je viens d'hériter d'un projet comme celui-ci. Et la toute première chose qu'ils voulaient faire a fait sauter le schéma. Clés de substitution FTW. Business Logic dans votre DB FTL.
Jason


11

Un peu hors sujet, mais je me sens obligé d'intervenir avec ...

Si votre clé primaire est un GUID, n'en faites pas un index cluster . Étant donné que les GUID ne sont pas séquentiels, les données seront réorganisées sur le disque pendant presque chaque insertion. (Beurk.) Si vous utilisez des GUID comme clés primaires, ils doivent être des index non clusterisés.


1
Très bon point - il faut faire la distinction entre le concept LOGIQUE d'une clé primaire (peut être valide pour utiliser un GUID pour cela, surtout si la réplication est impliquée), et le concept PHYSIQUE de la clé de clustering - qui ne devrait JAMAIS être un GUID depuis cela conduit à une fragmentation excessive de l'index
marc_s

3
Ce n'est en fait pas exact. Les données seront insérées dans l'ordre, ce qui, étant donné la nature aléatoire du GUID, pourrait finir par se trouver n'importe où dans la table. Au cas où il n'y aurait pas de place, un fractionnement de page se produira, mais certainement pas de "réorganisation sur le disque à chaque insertion" même pas fermé.
Ralph Shillington

@Ralph, vous avez raison, pas TOUS les insertions, mais suffisamment pour provoquer un impact 20x sur les performances. sql-server-performance.com/articles/per/…
Portman

La fonction newsequentialid () de SQL Server résout le problème de fragmentation d'index avec les GUID (bien que 24 octets soit encore un peu excessif si vous n'avez pas absolument besoin d'unicité globale). Voir msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE le

10

J'y vais toujours avec la clé de substitution. Une clé de substitution (généralement une colonne d'identité, un auto-incrémentation ou un GUID) est une clé dans laquelle la clé n'est pas présente dans les données elles-mêmes. Une clé naturelle, en revanche, est une clé qui, à elle seule, identifie de manière unique la ligne. Autant que je sache dans la vie, il n'y a pratiquement pas de véritables clés naturelles. Même des choses comme le SSN aux États-Unis ne sont pas une clé naturelle. Les clés primaires composites sont un désastre qui attend. Vous ne pouvez modifier aucune de ces données (ce qui est le principal inconvénient de toute clé naturelle, composite ou non), mais le pire est qu'avec une clé composite, vous devez maintenant perpétuer ces données clés dans chaque table associée. Quel gaspillage géant.

Maintenant, pour la sélection de la clé de substitution, je m'en tiens aux colonnes d'identité (je travaille principalement dans MS SQL Server). Les GUID sont trop volumineux et Microsoft recommande de ne pas les utiliser comme PK. Si vous avez plusieurs serveurs, tout ce que vous avez à faire est de faire l'incrément de 10 ou 20 ou tout ce que vous pensez du nombre maximum de serveurs dont vous aurez jamais besoin pour synchroniser / étendre, et simplement ajouter la graine pour chaque table sur chaque serveur suivant , et vous n'aurez jamais de collision de données.

Bien sûr, à cause de l'incrément, je fais de la colonne d'identité un BigInt (autrement connu sous le nom de long [64 bits]).

En faisant un peu de calcul, même si vous faites l'incrément de 100, vous pouvez toujours avoir 92 233 720 368 547 758 (> 92 quadrillions) lignes dans votre tableau.


9

Je pense que l'utilisation du mot «primaire», dans l'expression «clé primaire» est dans un vrai sens trompeur.

Tout d'abord, utilisez la définition selon laquelle une "clé" est un attribut ou un ensemble d'attributs qui doivent être uniques dans la table,

Ensuite, avoir une clé sert plusieurs objectifs souvent incompatibles entre eux.

  1. Pour utiliser en tant que conditions de jointure un ou plusieurs enregistrements dans les tables enfants qui ont une relation avec cette table parent. (Définition explicite ou implicite d'une clé étrangère dans ces tables enfants)
  2. (connexe) S'assurer que les enregistrements enfants doivent avoir un enregistrement parent dans l'onglet parent; e (La table enfant FK doit exister en tant que clé dans la table parent)
  3. Pour augmenter la performance des requêtes qui doivent localiser rapidement un enregistrement / une ligne spécifique dans le tableau.

  4. Pour assurer la cohérence des données en empêchant les lignes dupliquées qui représentent la même entité logique d'être insérées dans la table. (Ceci est souvent appelé une clé «naturelle», et devrait être constitué d'attributs de table (entité) qui sont relativement invariants.)

Clairement, toute clé non significative et non naturelle (comme un GUID ou un entier généré automatiquement est totalement incapable de satisfaire # 4.

Mais souvent, avec beaucoup (la plupart) des tables, une clé totalement naturelle qui peut fournir # 4 sera souvent composée de plusieurs attributs et sera excessivement large, ou si large que son utilisation à des fins # 1, # 2 ou # 3 sera inacceptable performances conséquencecs.

La réponse est simple. Utilise les deux. Utilisez une simple clé intégrale à génération automatique pour toutes les jointures et FK des autres tables enfants, mais assurez-vous que chaque table nécessitant la cohérence des données (très peu de tables ne le fait pas) dispose d'une clé unique naturelle alternative qui empêchera l'insertion de lignes de données incohérentes. .. De plus, si vous avez toujours les deux, alors toutes les objections contre l'utilisation d'une clé naturelle (et si elle change? Je dois changer chaque endroit où elle est référencée comme FK) deviennent sans objet, car vous ne l'utilisez pas pour cela. .. Vous ne l'utilisez que dans la seule table où il s'agit d'un PK, pour éviter les données dupliquées incohérentes ...

En ce qui concerne les GUID, soyez très prudent en les utilisant, car l'utilisation de guides dans un index peut réduire la fragmentation de l'index. Les algorithmes les plus courants utilisés pour les créer placent la partie "aléatoire" du GUID dans les positions binaires les plus significatives ... Cela augmente la nécessité d'une défragmentation / réindexation d'index régulière à mesure que de nouvelles lignes sont ajoutées.


La fonction newsequentialid () de SQL Server résout le problème de fragmentation d'index des GUID (bien que 24 octets soit encore un peu excessif si vous n'avez pas absolument besoin d'unicité globale). Voir msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE le

oups, je voulais dire 16 octets.
ErikE le

8

Une chose que vous ne devriez jamais faire est d'utiliser une clé intelligente. C'est une clé où les informations sur l'enregistrement sont codées dans la clé elle-même, et cela finira par vous mordre.

J'ai travaillé à un endroit, où la clé primaire était l'ID de compte, qui était une combinaison de lettres et de chiffres. Je ne me souviens pas de détails, mais, par exemple, les comptes qui étaient d'un certain type, seraient dans la gamme 600, et d'un autre type, commençaient par 400. C'était génial, jusqu'à ce que ce client décide de demander les deux types de travail. Ou changé le type de travail qu'ils faisaient.

Un autre endroit, utilisé l'emplacement dans l'arborescence comme clé primaire pour les enregistrements. Il y aurait donc des enregistrements comme celui-ci.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Bien sûr, la première chose que les clients voulaient était un moyen de déplacer les articles dans l'arborescence. L'ensemble des logiciels est mort avant que cela ne se produise.

S'il vous plaît, s'il vous plaît, s'il vous plaît, si vous écrivez du code que je dois maintenir, veuillez ne pas utiliser de clé intelligente!


Je suis entièrement d'accord. Smartkeys = stupide.
Robert C. Barth

2
Cela ne signifie pas pour autant que les touches naturelles sont stupides. Mais bon point.

4

Je suis fan de l'incrémentation automatique comme clé primaire. Je sais au fond de moi qu'il s'agit d'une échappatoire, mais cela rend si facile de trier les données par quand elles ont été ajoutées (ORDER BY ID DESC, f'r instance).

3 colonnes semblent terriblement difficiles à analyser humainement.

Et c'est le compromis - de combien de capacité relationnelle avez-vous besoin, par rapport à rendre CE TABLEAU ICI compréhensible par un humain qui l'interroge (par rapport à la procédure stockée ou à l'interface de programmation).

l'auto-incrémentation est pour nous les humains. :-(


4

En général, cela dépend.

Personnellement, j'aime les ints auto-incrémentés.

Mais, une chose que je peux vous dire est de ne jamais faire confiance aux données provenant d'autres sources comme votre clé. Je le jure, chaque fois que je fais ça, ça me mord. Eh bien, plus jamais!


3

Il doit y avoir au moins 3 colonnes qui constituent la clé primaire.

Je ne comprends pas ça.

Parlez-vous d'une "clé naturelle", par exemple "nom et date de naissance"? Une clé naturelle peut être idéale si elle existe, mais la plupart des candidats pour une clé naturelle ne sont pas uniques (plusieurs personnes portant le même nom) ou ne sont pas constantes (quelqu'un peut changer de nom).

Int / BigInt dont l'auto-incrémentation sont des clés primaires assez bonnes.

Je préfère Guid. Un problème potentiel avec l'auto-incrémentation est que la valeur (par exemple, "order id") est attribuée par l'instance de base de données (par exemple par la "base de données des ventes") ... ce qui ne fonctionnera pas entièrement (au lieu de cela, vous commencez à avoir besoin de clés composées) si vous devez jamais fusionner des données créées par plus d'une instance de base de données (par exemple à partir de plusieurs bureaux de vente, chacun avec sa propre base de données).


Les clés primaires doivent être uniques, mais ne doivent pas nécessairement être constantes. D'où les clés étrangères déclarées avec "ON UPDATE CASCADE". Mais supposer que les clés primaires sont constantes permet de simplifier de nombreuses applications. C'est l'un des avantages des clés de substitution.
Bill Karwin

3

GUID RE

Faites attention si cela va être une très VRAIMENT VRAIMENT VRAIMENT grosse base de données, beaucoup de charge et un accès rapide.

Lors de mon dernier travail, où nous avions des bases de données de 100 à 500 millions d'enregistrements, nos spécialistes des bases de données se sont fermement opposés aux GUID et à un nombre décimal de taille appropriée. Ils ont estimé que (sous Oracle) la différence de taille dans la mémoire interne pour une chaîne Guid - par rapport à une valeur décimale ferait une différence très notable dans les recherches. (Clés plus grandes = arbres plus profonds à traverser)

La nature aléatoire des GUID réduit également considérablement le facteur de remplissage des pages d'index, ce qui augmente considérablement le déchirement et les E / S de disque.


"Réduit le facteur de remplissage"? Je ne sais pas ce que cela pourrait signifier. Le facteur de remplissage est une transaction unique, définie comme le pourcentage d'espace libre demandé au niveau feuille de l'index au moment de la création de l'index. Les valeurs GUID par leur distribution de nature aléatoire sur la largeur du niveau feuille sur les insertions dans cet espace libre fourni par le facteur de remplissage.
Ralph Shillington

1
Depuis quand un GUID est-il une chaîne? Les GUID doivent être stockés en interne sous forme de 16 octets par tout SGBD respectable. Le stockage à 32 octets dans la représentation hexadécimale serait inadmissible! (ou 36 avec des tirets, ou 38 avec des accolades)
ErikE

2

Colonnes à incrémentation automatique. Je suis capable de faire fonctionner mon code de manière transparente avec SQL Server ou Oracle, l'un utilisant l'identité l'autre utilisant des séquences via mon DAL, et je ne pourrais pas être plus heureux. Je suis d'accord, les GUID sont parfois nécessaires si vous effectuez une réplication ou envoyez des données pour les recevoir plus tard après le traitement.


2

J'ai toujours utilisé une clé de substitution - un entier à auto-incrémentation appelé «id». Je peux voir de nombreuses raisons de le faire même lorsqu'une autre option est évidente:

  • Cohérence
  • Indépendant des données (uniques, non détruites par les changements de format)
  • Lisible par l'homme

... et aucune raison raisonnable de ne pas:

  • Ambiguïté dans les jointures? - Les tables d'aliasing est une meilleure pratique, à mon humble avis
  • Tables optimales? - La suppression d'un octet par entrée est une optimisation prématurée, à mon humble avis
  • Décision par table? - Plus cohérent
  • Problèmes de mise à l'échelle? - Hein? Pourquoi?
  • Structure de données hiérarchique? - C'est de la dénormalisation, un tout autre sujet de religion. Qu'il suffise de dire que je suis fan dans quelques circonstances en théorie, mais jamais en pratique :)

les raisons raisonnables contre lesquelles je n'ai pas encore pensé ou rencontrées sont toujours les bienvenues ...


1

C'est un classique "ça dépend". Il n'y a pas une seule bonne réponse pour chaque projet. J'aime différentes choses pour différentes situations. Cela dépend si j'utilise un ORM et ce qu'il prend en charge. Cela dépend de l'architecture globale (distribuée ou non, etc.). Choisissez simplement celui qui, selon vous, fonctionnera et passez à la discussion sur les onglets et les espaces.


Il souhaite toujours savoir COMMENT cela dépend; Ce n'est qu'en prenant conscience de cela que l'on peut se faire confiance pour choisir ...
Nicholas Leonard

1

J'ai tendance à utiliser l'option n ° 1 ou n ° 3 selon la taille, le nombre de personnes qui se connectent et s'il s'agit d'une situation de serveur de bases de données multiples ou non.

L'option n ° 2 n'a pas beaucoup de sens pour moi. Si l'un des trois n'est pas suffisant pour identifier un enregistrement unique, il est possible (sans passer par des opérations supplémentaires) que deux enregistrements apparaissent avec les mêmes valeurs dans les trois colonnes. Si vous souhaitez appliquer l'unicité à n'importe quelle combinaison des trois, ajoutez simplement un index pour eux.


1

Je n'utilise qu'un int auto-incrémenté ou un GUID. 99% du temps, j'utilise des int auto-incrémentés. C'est exactement ce que j'ai appris à utiliser lorsque j'ai découvert les bases de données pour la première fois et que je n'ai jamais rencontré de raison de ne pas les utiliser (même si je connais les raisons pour lesquelles un GUID serait meilleur).

J'aime les incréments automatiques car cela aide à la lisibilité. Par exemple, je peux dire "jetez un œil à l'enregistrement 129383" et il est assez facile pour quelqu'un d'entrer et de le trouver. Avec un GUID c'est presque impossible à faire.


2
Pourquoi dites vous cela? Il semble que de nombreuses personnes utilisent un entier auto-incrémenté. Cela ne peut pas être si grave si cela fonctionne et fonctionne bien pour ce dont vous avez besoin.
dtc le

1

Au-delà d'une réponse définitionnelle de base, ce qui constitue une bonne clé primaire est largement laissé aux arguments de la religion et de la salle de repos. Si vous avez quelque chose qui est et sera toujours mappé de manière unique à une ligne individuelle, cela fonctionnera bien en tant que clé primaire. Passé ce stade, il y a d'autres considérations:

  • La définition de la clé primaire n'est-elle pas trop complexe? Évite-t-elle d'introduire une complexité inutile dans le but de suivre une «meilleure pratique»?
  • Existe-t-il une meilleure clé primaire possible qui nécessiterait moins de surcharge pour la base de données à gérer (par exemple INTEGER vs VARCHAR, etc.)?
  • Suis-je absolument certain que l'unicité et l'invariant de définition de ma clé primaire ne changeront pas?

Ce dernier est probablement ce qui incite la plupart des gens à utiliser des éléments tels que les GUID ou des colonnes d'entiers auto-incrémentées, car en s'appuyant sur des éléments tels que les adresses, les numéros de téléphone, les prénoms / noms, etc., ne le coupez pas. Le seul invariant des personnes auquel je peux penser est les SSN, mais je ne suis même pas sûr à 100% que ceux-ci resteront à jamais uniques.

Espérons que cela contribue à ajouter de la clarté ...


Il existe des cas historiques où les SSN ne sont pas uniques.
Bill Karwin

1

La façon dont j'aborde les clés primaires (et je pense que c'est la meilleure) est d'éviter d'avoir une approche «par défaut». Cela signifie qu'au lieu de simplement taper sur un entier auto-incrémenté et de l'appeler un jour, je regarde le problème et dis "y a-t-il une colonne ou un groupe de colonnes qui sera toujours unique et ne changera pas?" Si la réponse est oui, j'adopte cette approche.


Cela signifie-t-il que vous «évitez l'incrémentation automatique des entiers chaque fois que vous le pouvez»? D'après ce que j'ai compris, les experts du secteur pensaient que les meilleures performances sur les bases de données à grande échelle provenaient de PK à une seule colonne, indexées et à signature minimale.
Hardryv

1
J'ai toujours pensé que les experts utilisaient le meilleur outil pour le travail
Andrew G. Johnson

1

Presque toujours des nombres entiers.

Ils ont d'autres bonnes raisons en plus d'être plus petits / plus rapides à traiter. Lequel préférez-vous écrire - "404040" ou "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?


Ce dernier peut être un entier, avec des tirets ajoutés et en base 16. Mais oui, 404040 est plus rapide à traiter que le GUID long. Là encore, 0 est encore plus rapide à traiter car il ne nécessite pas un seul bit de données!
strager

1

Ce n'est que légèrement pertinent, mais une chose que j'ai commencé à faire récemment lorsque j'ai de petites tables de classification (essentiellement celles qui représenteraient les ENUM dans le code) est que je vais faire de la clé primaire un char (3) ou char (4). Ensuite, je rends ces clés primaires représentatives de la valeur de recherche.

Par exemple, j'ai un système de devis pour nos agents commerciaux internes. Nous avons des "Catégories de coûts" auxquelles chaque élément de ligne de devis est affecté à l'un des ... J'ai donc une table de recherche de type appelée 'tCostCategories', où la clé primaire est 'MTL', 'SVC', 'TRV', 'TAX', «ODC». D'autres colonnes de la table de recherche stockent plus de détails, tels que la signification anglaise normale des codes, «Matériel», «Service», «Voyage», «Taxes», «Autres coûts directs», etc.

C'est vraiment bien car il n'utilise pas plus d'espace qu'un int, et lorsque vous regardez les données source, vous n'avez pas besoin de lier la table de recherche pour savoir quelle est la valeur. Par exemple, une ligne de devis peut ressembler à ceci:

1 Numéro de pièce 40 $ MTL
2 Autre numéro de pièce 29,99 $ SVC
3 Numéro de pièce2 150 $ TRV

Il est beaucoup plus facile d'utiliser un int pour représenter les catégories, puis de relier 1, 2, 3 sur toutes les lignes - vous avez les données juste là devant vous, et la performance ne semble pas du tout affectée (pas que je '' vraiment testé.)

En ce qui concerne la vraie question ... j'aime les identificateurs uniques RowGUID. Je ne suis pas à 100% là-dessus, mais toutes les lignes n'ont-elles pas de RowGuid interne de toute façon ?? Si tel est le cas, utiliser RowGuid prendrait en fait moins de place que ints (ou quoi que ce soit d'autre d'ailleurs). Tout ce que je sais, c'est que si c'est assez bon pour M $ à utiliser dans GreatPlains, alors c'est assez bien pour moi. (Dois-je esquiver ??)


1

Oh, une autre raison pour laquelle j'utilise des GUID - j'utilise une structure de données hiérarchique. Autrement dit, j'ai une table «Entreprise» et une table «Fournisseur» pour lesquelles les clés primaires correspondent. Mais j'ai aussi une table «Fabricant» qui «hérite» également de Company. Les champs communs aux fournisseurs et aux fabricants n'apparaissent pas dans ces tableaux - ils apparaissent dans Société. Dans cette configuration, utiliser des int est beaucoup plus douloureux que les Guids. À tout le moins, vous ne pouvez pas utiliser de clés primaires d'identité.


1
Oui, vous pouvez, vous ne faites tout simplement pas en sorte que les tables de sous-types aient la propriété d'identité, à la place elles obtiennent des inserts explicites de la valeur de la table de supertype. Veuillez consulter stackoverflow.com/questions/2112882/…
ErikE le

1

J'aime les clés naturelles, chaque fois que je peux leur faire confiance. Je suis prêt à payer un petit prix de performance afin d'utiliser des clés qui ont du sens pour les experts en la matière.

Pour les tableaux qui décrivent des entités, il doit y avoir une clé naturelle simple qui identifie les instances individuelles de la même manière que les sujets. Si le sujet n'a pas d'identifiants fiables pour l'une des entités, je recourrai à une clé de substitution.

Pour les tables qui décrivent les relations, j'utilise une clé composée, où chaque composant fait référence à une entité qui participe à la relation, et donc à une ligne dans une table d'entité. Encore une fois, la performance de l'utilisation d'une clé composée est généralement minime.

Comme d'autres l'ont souligné, le terme «clé primaire» est un peu trompeur. Dans le modèle de données relationnelles, le terme utilisé est «clés candidates». Il peut y avoir plusieurs clés candidates pour une seule table. Logiquement, chacun est aussi bon qu'un autre. Choisir l'un d'entre eux comme "primaire" et faire toutes les références via cette clé est simplement un choix que le concepteur peut faire.


Veuillez décrire quelques exemples de clés naturelles fiables?
ErikE

1
"digne de confiance" n'est pas une propriété d'une clé en soi. Il s'agit plutôt de la clé dans le contexte des personnes qui fournissent les données. Si vous écrivez une application à vendre à quelqu'un qui gérera réellement les données, vous devez deviner quelles clés seront ou non dignes de confiance pour le client. Compte tenu de la variété des clients, vous allez presque sûrement vous tromper pour une fraction de votre clientèle.
Walter Mitty

Cela dit, voici un exemple de clé à laquelle nous avions confiance il y a longtemps. Nous avions une base de données sur les cours. Il comprenait des manuels et autres matériels de cours sur les cours, les offres de cours programmées, les instructeurs qualifiés pour enseigner les cours, les prérequis des cours, les frais de scolarité, etc. Lorsque le développement d'un cours a créé un nouveau cours, l'une des premières choses qu'ils ont faite a été d'attribuer un code de cours. Ils étaient chargés de s'assurer que les codes de cours étaient uniques et que les cours ne changeaient jamais leur code, une fois attribués. Cela faisait partie des données qui nous ont été fournies.
Walter Mitty

Un autre bon exemple de clé naturelle de confiance est le VIN (Vehicle Identification Number). Au cours des dernières années, chaque véhicule vendu comme neuf est associé à un NIV. On peut leur faire confiance pour être uniques et immuables.
Walter Mitty

1

Guids.period.

Dans le cas où vous auriez besoin d'évoluer ou d'attribuer la clé primaire par d'autres moyens, ils seront votre ami. Vous pouvez ajouter des index pour tout le reste.


mise à jour pour clarifier ma déclaration.

J'ai travaillé sur de nombreux types de sites. Des petites offres de serveur unique aux grandes offres avec plusieurs serveurs de base de données et Web. Il y a certainement eu des applications qui auraient été très bien avec l'incrémentation automatique des ints en tant que clés primaires. Cependant, cela ne correspond pas au modèle de la façon dont je fais les choses.

Lorsque vous utilisez un GUID, vous pouvez générer l'ID n'importe où. Il peut être généré par un serveur distant, votre application Web, dans la base de données elle-même ou même dans plusieurs bases de données dans une situation multimaître.

D'un autre côté, un INT auto-incrémenté ne peut être généré en toute sécurité que dans la base de données primaire. Encore une fois, cela pourrait convenir si vous avez une application qui sera intimement liée à ce serveur de base de données de sauvegarde et que la mise à l'échelle n'est pas quelque chose qui vous préoccupe.

Bien sûr, l'utilisation de GUID signifie que vous devez avoir des processus de réindexation nocturnes. Cependant, si vous utilisez autre chose qu'un INT auto-incrémenté, vous devez le faire quand même. Heck, même avec un INT comme principal, il est probable que vous ayez d'autres index qui doivent être régénérés pour gérer la fragmentation. Par conséquent, l'utilisation de GUID n'ajoute pas exactement un autre problème car ces tâches doivent être exécutées malgré tout.

Si vous jetez un œil aux applications plus volumineuses, vous remarquerez quelque chose d'important: elles utilisent toutes des GUID encodés en Base64 comme clés. La raison en est simple, l'utilisation de GUID vous permet de passer facilement à l'échelle , alors qu'il peut y avoir beaucoup d'obstacles à franchir lors de la tentative de mise à l'échelle des INT.

Notre dernière application traverse une période d'insertions lourdes qui dure environ un mois. Après cela, plus de 90% des requêtes sont toutes sélectionnées pour la création de rapports. Pour augmenter la capacité, je peux installer des serveurs de base de données supplémentaires pendant cette grande période d'insertion; puis les fusionner facilement en une seule base de données pour la création de rapports. Tenter de faire cela avec des INT serait un cauchemar absolu.

Franchement, chaque fois que vous mettez en cluster une base de données ou que vous configurez une réplication, le serveur de base de données vous demandera de toute façon d'avoir des GUID sur la table. Donc, si vous pensez que votre système pourrait avoir besoin de se développer, choisissez celui qui est bon.


Vous avez déjà examiné le facteur de remplissage de vos index? La nature aléatoire des GUID en fait du fromage suisse - réduisant considérablement leur efficacité.
stephbu

2
"Guids.period": C'est tellement faux. Les GUID doivent être utilisés le cas échéant. Comme l'a souligné l'autre commentateur, cela peut faciliter la vie de programmeur, mais affecte la taille globale et les performances de la base de données.
Mitch Wheat

À la fin de la journée, je peux faire évoluer mes applications sur plusieurs serveurs de base de données sans problème. Mais je suppose que vous travaillez sur de petits sites.
NotMe

3
GUID peut être correct pour la clé primaire logique, mais JAMAIS JAMAIS utiliser une colonne GUID comme clé de CLUSTERING - vous serez noyé dans la fragmentation de l'index conduisant à des performances
médiocres

Je ne proclamerais certainement pas «Guids.period». sur ce sujet - en fait, même dans un secteur si rempli de «meilleures pratiques», ce genre de déclaration vous met sur un terrain instable par défaut (en particulier avec cette déclaration). Tout ce qui est aussi douloureux à traiter qu'un GUID nécessite une justification solide et, comme le dit JL, je pense que la plupart d'entre nous le considéreraient comme un dernier recours. C'est comme si vous postiez sans lire le reste du fil de discussion.
Hardryv

0

C'est un sujet complexe que vous l'ayez réalisé ou non. Pourrait tomber sous la section de cette FAQ StackOverflow.

Quel genre de questions ne dois-je pas poser ici?

Évitez de poser des questions subjectives, argumentatives ou nécessitant une discussion approfondie. C'est un endroit pour les questions auxquelles on peut répondre!

Cela fait l'objet de débats depuis des années et continuera de l'être pendant des années. Le seul indice de consensus que j'ai vu est que les réponses sont quelque peu prévisibles selon que vous demandez à un gars OO (les GUID sont la seule voie à suivre!), Un modeleur de données (les clés naturelles sont la seule voie à suivre!), ou un DBA orienté performance (les INT sont la seule solution!).


Je ne laisserai pas la discussion durer trop longtemps. J'étais simplement curieux de voir le consensus général.
Perpetualcoder

1
Je dis posez toutes les questions que vous souhaitez! Sinon, cette communauté deviendra statique et surcontrôlée comme semble l'être Wikipédia. Il me semble que parfois, vous devez laisser les gens demander ce qu'ils veulent. Faites-leur confiance, et ils pourraient se faire confiance!
Nicholas Leonard
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.