Clés de substitution vs clés naturelles / commerciales [fermé]

174

Nous y revoilà, le vieil argument se pose encore ...

Aurions-nous mieux une clé métier comme clé primaire, ou aurions-nous plutôt un identifiant de substitution (c'est-à-dire une identité SQL Server) avec une contrainte unique sur le champ de clé métier?

Veuillez fournir des exemples ou des preuves pour étayer votre théorie.

Manrico Corazzi
la source
24
@Joachim Sauer: Un argument sur la question de savoir si une chose est subjective peut être lui-même subjectif, sans que cela ne concerne en aucune façon l'objectivité ou la subjectivité de la chose en question. À moins que vous ne soyez prêt à énoncer les critères objectifs exacts qui rendent quelque chose d'objectif. Il y a des choses appelées «concepts ouverts» comme le nombre de poils nécessaires pour faire une barbe. On peut objectivement dire qu'une personne sans poils au menton n'a pas de barbe et qu'une personne avec 5000 poils d'un pouce de long a une barbe, mais quelque part au milieu, un jugement subjectif est nécessaire pour prendre une décision objective.
ErikE
@Manrico: il suffit de se demander ceci: si je n'utilise pas de clé de substitution, ma clé primaire sera-t-elle toujours immuable? Si la réponse est non, vous devriez sérieusement envisager d'utiliser une clé de substitution. De plus, si la clé primaire est composée même partiellement d'entrées utilisateur, vous devez envisager d'utiliser une clé de substitution. Pourquoi? En raison du risque d'anomalies des données.
code4life
@TylerRick Mais ce n'est pas une très bonne question. Il demande une solution qui soit généralement applicable à toutes les situations, alors qu'il n'y en a manifestement pas une, comme le prouve la «guerre de religion» dont le demandeur est parfaitement conscient (citation: «On y va encore, le vieil argument se pose encore. .. "). Au lieu de se demander si le monde a changé et enfin une raison impérieuse de choisir un côté à tout moment a été fournie, il est préférable de continuer à poser cette question encore et encore pour chaque situation concrète, et de poster sur SO lorsque vous n'êtes pas sûr. . Cela ne fait qu'éliciter le dogmatisme.
MarioDS

Réponses:

97

Tous les deux. Prenez votre gâteau et mangez-le.

Souvenez-vous qu'il n'y a rien de spécial à propos d'une clé primaire, sauf qu'elle est étiquetée comme telle. Ce n'est rien de plus qu'une contrainte NOT NULL UNIQUE, et une table peut en avoir plusieurs.

Si vous utilisez une clé de substitution, vous souhaitez toujours une clé métier pour garantir l'unicité selon les règles métier.

Ted
la source
7
Si vous avez plusieurs clés «candidates» (champs ou collections de champs de même taille qui ne sont PAS NULL UNIQUE), vous êtes probablement en violation de la forme normale de Boyce-Codd. BCNF est au-delà de 3NF, donc peu de gens s'en inquiètent. Il y a des situations, cependant, où être au BCNF est très utile.
Alan le
2
D'accord. La vraie question devrait être: Dois-je ajouter une clé de substitution unique à mes tables? Une toute autre question est de savoir quoi utiliser pour une clé primaire logique. Ce ne sont essentiellement que des contraintes d'index uniques non nulles.
dkretz
1
"Chaque problème est résolu avec un autre niveau d'indirection" ... Les clés de substitution ne sont que cela: un autre niveau d'indirection
Steve Schnepp
5
Je trouve étrange que de nombreux commentaires semblent affirmer qu'on ne peut pas établir une relation sans clé de substitution. Dans de nombreux cas, la clé de substitution est superflue. Pourquoi ajouter quelque chose qui n'apporte aucune valeur mais ajoute une dette technique (et dans certains cas, fait qu'un résultat par ailleurs unique devient soudainement non unique).
Wil Moore III
2
C'est plus que la contrainte NOT NULL UNIQUE. La clé primaire est utilisée comme un index cluster qui détermine l'ordre physique de vos données. En général, Integer est facile à équilibrer car il s'incrémente séquentiellement et vos données s'ajouteront à l'EOF sur le disque. Si vous utilisez moins de données séquentielles telles que du texte ou des GUID (UUID), il y aura beaucoup plus d'E / S disque et d'efforts pour équilibrer l'index, je pense que c'est une sorte de grande différence
Jin
124

Quelques raisons d'utiliser des clés de substitution:

  1. Stabilité : la modification d'une clé en raison d'un besoin professionnel ou naturel aura un impact négatif sur les tables associées. Les clés de substitution doivent rarement, voire jamais, être modifiées car il n'y a pas de signification liée à la valeur.

  2. Convention : vous permet d'avoir une convention de dénomination de colonne de clé primaire standardisée plutôt que d'avoir à réfléchir à la façon de joindre des tables avec différents noms pour leurs PK.

  3. Vitesse : selon la valeur et le type PK, une clé de substitution d'un entier peut être plus petite, plus rapide à indexer et à rechercher.

Jay Shepherd
la source
2
Maintenant, après avoir beaucoup lu sur les clés de substitution et les clés naturelles, je pense qu'il est préférable d'utiliser des clés de substitution. Mais, sur ma base de données, les clés naturelles (un NVARCHAR (20)) doivent être uniques. Je ne comprends pas comment je peux obtenir plus de vitesse si je dois vérifier toutes les données de cette colonne pour ne répéter aucune valeur (en utilisant une contrainte NOT NULL UNIQUE) sur chaque insertion.
VansFannel
70

Il semble que personne n'ait encore rien dit en faveur des clés non substitutives (j'hésite à dire «naturelles»). Alors voilà ...

Un inconvénient des clés de substitution est qu'elles n'ont aucun sens (citées comme un avantage par certains, mais ...). Cela vous oblige parfois à joindre beaucoup plus de tables dans votre requête que ce qui devrait vraiment être nécessaire. Comparer:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

contre:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

À moins que quelqu'un ne pense sérieusement que ce qui suit est une bonne idée?:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Mais" quelqu'un dira, "que se passe-t-il lorsque le code pour MYPROJECT ou VALID ou HR change?" A quoi ma réponse serait: "pourquoi auriez-vous besoin de le changer?" Ce ne sont pas des clés «naturelles» dans le sens où un organisme extérieur va légiférer que dorénavant «VALIDE» devrait être recodé comme «BON». Seul un petit pourcentage de clés «naturelles» entrent vraiment dans cette catégorie - le SSN et le code postal étant les exemples habituels. J'utiliserais certainement une clé numérique dénuée de sens pour des tables comme Personne, Adresse - mais pas pour tout , ce que , pour une raison quelconque, la plupart des gens ici semblent prôner.

Voir aussi: ma réponse à une autre question

Tony Andrews
la source
14
-1 Les clés naturelles en tant que clé primaire ont le problème que pour chaque table enfant, vous devez ajouter la clé du parent qui peut être composée de plus d'un champ (au lieu d'un seul ce qui est le cas d'une clé de substitution) et aussi l'enfant clé. Imaginez donc ce qui suit où à partir de TABLEA la relation est 1-0 .. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Vous voyez le problème? La clé parente est propagée dans les tables enfants. Que se passerait-il si la clé primaire de TABLEA change? Maintenant, vous devriez également refactoriser toutes les tables enfants PK.
Alfredo Osorio
9
@Alfredo: oui bien sûr, il y a un compromis. Cependant, au cours de mes 20 ans et plus d'expérience, j'ai rarement vu la définition du changement PK d'une table. Si cela arrivait régulièrement, j'éviterais probablement aussi les clés naturelles. En réalité, dans les très rares occasions où cela se produit, je suis prêt à subir le coup de l'impact prolongé.
Tony Andrews
10
Je ne suis pas d'accord. C'est souvent le cas lorsqu'un organisme extérieur (le client) légifère qu'une clé naturelle doit être éditée, et donc propagée dans tout le système. Je vois cela arriver régulièrement. La seule façon dont vous pouvez être sûr que la clé n'aura jamais besoin de changer est lorsqu'elle est par définition dénuée de sens. En outre, les bases de données modernes gèrent les jointures internes de manière extrêmement efficace, de sorte que les gains d'espace potentiellement importants liés à l'utilisation de substituts l'emportent généralement sur l'avantage de ne pas avoir à faire autant de jointures internes.
TTT
8
@TTT: Ensuite, la conception était faible au début. Encore une fois, c'est là que les hommes se séparent des garçons: faire le bon choix de quand utiliser la clé naturelle, et quand utiliser un substitut. Vous décidez cela sur une base par table, pas comme un dogme général.
DanMan
7
J'ai également plus de 20 ans d'expérience et je partage votre opinion. Une fois, j'ai créé un entrepôt de données oracle avec des clés de substitution, et la maintenance des données était un enfer. Vous ne pouvez tout simplement jamais accéder directement à vos données. vous devez toujours écrire des requêtes pour tout, ce qui rend les clés de substitution tout simplement horribles à gérer.
SQL Police
31

La clé de substitution n'aura JAMAIS de raison de changer. Je ne peux pas en dire autant des clés naturelles. Noms de famille, e-mails, numéros ISBN - ils peuvent tous changer un jour.

Rimantas
la source
31

Les clés de substitution (généralement des entiers) ont la valeur ajoutée de rendre vos relations de table plus rapides, et plus économiques en termes de stockage et de vitesse de mise à jour (encore mieux, les clés étrangères n'ont pas besoin d'être mises à jour lors de l'utilisation de clés de substitution, contrairement aux champs de clé métier, qui changent de temps en temps).

La clé primaire d'une table doit être utilisée pour identifier de manière unique la ligne, principalement à des fins de jointure. Pensez à une table de personnes: les noms peuvent changer et ils ne sont pas garantis uniques.

Pensez aux entreprises: vous êtes une entreprise Merkin heureuse qui fait affaire avec d'autres entreprises à Merkia. Vous êtes assez intelligent pour ne pas utiliser le nom de l'entreprise comme clé primaire, vous utilisez donc l'ID d'entreprise unique du gouvernement de Merkia dans son intégralité de 10 caractères alphanumériques. Merkia modifie ensuite les identifiants de l'entreprise car ils pensaient que ce serait une bonne idée. C'est bon, vous utilisez la fonctionnalité de mises à jour en cascade de votre moteur de base de données, pour un changement qui ne devrait pas vous impliquer en premier lieu. Plus tard, votre entreprise se développe et maintenant vous travaillez avec une entreprise à Freedonia. L'identifiant de la société franconienne comprend jusqu'à 16 caractères. Vous devez agrandir la clé primaire de l'ID de société (également les champs de clé étrangère dans les commandes, les problèmes, les transferts d'argent, etc.), en ajoutant un champ Pays dans la clé primaire (également dans les clés étrangères). Aie! Guerre civile à Freedonia, c'est s divisé en trois pays. Le nom du pays de votre associé doit être remplacé par le nouveau; mises à jour en cascade à la rescousse. BTW, quelle est votre clé primaire? (Pays, CompanyID) ou (CompanyID, Country)? Ce dernier facilite les jointures, le premier évite un autre index (ou peut-être plusieurs, si vous voulez que vos commandes soient également regroupées par pays).

Tout cela n'est pas une preuve, mais une indication qu'une clé de substitution pour identifier de manière unique une ligne pour toutes les utilisations, y compris les opérations de jointure, est préférable à une clé métier.

tzot
la source
Vous gagnez tous les internets avec le nom d'utilisateur le plus cool!
Iain Holder
1
C'est à peu près ce qu'est un vote défavorable: «Je ne suis pas d'accord avec ça».
jcollum
5
L'info-bulle de la flèche vers le bas indique "Cette réponse n'est pas utile", et non "Je ne suis pas d'accord avec cela". Peut-être que dans cette réponse spécifique, les significations sont proches, mais elles ne sont généralement pas les mêmes.
tzot
1
Si quelqu'un pense que votre réponse est fausse, alors il (/ elle) pensera aussi que cela conduit l'interrogateur dans la mauvaise direction (opposée à la bonne direction), et jugera donc votre réponse comme étant encore pire que "inutile", justifier dans son esprit un vote défavorable.
Erwin Smout
1
Oui, les clés de substitution sont une maladie. Un fuit dans la nature et vous l'utilisez comme clé p. Vous avez donc maintenant besoin de votre propre clé de substitution. Ensuite, votre clé fuit dans la nature (par exemple via une URL) et la maladie se propage.
Samuel Danielson
25

Je déteste les clés de substitution en général. Ils ne doivent être utilisés que lorsqu'aucune clé naturelle de qualité n'est disponible. Il est plutôt absurde quand on y pense, de penser que l'ajout de données sans signification à votre tableau pourrait améliorer les choses.

Voici mes raisons:

  1. Lorsque vous utilisez des clés naturelles, les tables sont regroupées de la manière dont elles sont le plus souvent recherchées, accélérant ainsi les requêtes.

  2. Lorsque vous utilisez des clés de substitution, vous devez ajouter des index uniques sur les colonnes de clé logique. Vous devez toujours empêcher les données en double logique. Par exemple, vous ne pouvez pas autoriser deux organisations portant le même nom dans votre table d'organisation même si le pk est une colonne d'ID de substitution.

  3. Lorsque des clés de substitution sont utilisées comme clé primaire, il est beaucoup moins clair quelles sont les clés primaires naturelles. Lors du développement, vous voulez savoir quel ensemble de colonnes rend la table unique.

  4. Dans une à plusieurs chaînes de relations, les chaînes de clés logiques. Ainsi, par exemple, les organisations ont de nombreux comptes et les comptes ont de nombreuses factures. Ainsi, la clé logique de l'organisation est OrgName. La clé logique des comptes est OrgName, AccountID. La clé logique de Invoice est OrgName, AccountID, InvoiceNumber.

    Lorsque des clés de substitution sont utilisées, les chaînes de clés sont tronquées en ayant uniquement une clé étrangère pour le parent immédiat. Par exemple, la table Facture n'a pas de colonne OrgName. Il n'a qu'une colonne pour le AccountID. Si vous souhaitez rechercher des factures pour une organisation donnée, vous devrez rejoindre les tables Organisation, Compte et Facture. Si vous utilisez des clés logiques, vous pouvez interroger directement la table d'organisation.

  5. Le stockage des valeurs de clé de substitution des tables de recherche entraîne le remplissage des tables avec des entiers sans signification. Pour afficher les données, des vues complexes doivent être créées qui se joignent à toutes les tables de recherche. Une table de recherche est censée contenir un ensemble de valeurs acceptables pour une colonne. Il ne doit pas être codifié en stockant une clé de substitution d'entier à la place. Il n'y a rien dans les règles de normalisation qui suggère que vous devriez stocker un entier de substitution au lieu de la valeur elle-même.

  6. J'ai trois livres de bases de données différents. Aucun d'entre eux n'utilise des clés de substitution.

Ken
la source
7
Je déteste les clés de substitution, sauf quand elles sont nécessaires. Ils sont nécessaires lorsque l'entreprise utilise une clé naturelle sujette à de nombreuses erreurs et refuse de tolérer une base de données affectée par ces erreurs.
Walter Mitty
26
-1: J'ai écrit et maintenu des dizaines d'applications. Ceux qui ont le plus de problèmes liés aux données étaient ceux utilisant des clés naturelles.
Falcon le
6
Certains de vos points supposent que la clé de substitution doit être le PK ou doit être la colonne en cluster - ce n'est pas vrai. Vos points 1 et 5 ignorent le fait que les nombres entiers font 4 octets et que les clés naturelles sont presque toujours nombreuses, beaucoup plus d'octets. Et, chaque index non clusterisé doit répéter les octets de ces clés naturelles qui se trouvent dans l'index clusterisé, de sorte que les tables et les index de votre base de données de clés naturelles auront beaucoup, beaucoup moins de lignes par page, ce qui se traduit par des performances de lecture bien pires. , ce qui rend les requêtes plus lentes , pas plus rapides.
ErikE
3
Autre raison contre les clés naturelles (exemples: numéros atomiques, VIN, etc.), la logique métier peut changer ce qui augmente le type de données. Par exemple - Avant: Suivi des charges d'atomes, Après: Suivi des charges d'atomes et de composés. Avant: Suivi des véhicules à moteur pour la capacité de charge. Après: Ajout d'avions, de bateaux, de vélos et de personnes pour la capacité de charge.
forforf
3
Je suppose que vous n'avez pas de tables où la clé primaire est composée même partiellement de 1) tout attribut qui peut et changera), ou 2) de l'entrée de l'utilisateur (par exemple, des listes de recherche générées dynamiquement). Si vous ne pouvez pas garantir l'immuabilité des clés, vous devrez alors mettre à jour toutes ces relations d'entité par code ou par des scripts de «correction» manuels. Si vous n'avez jamais eu à faire cela ... Je suppose que votre base de données est à la fois sans clé de substitution et ... inhabituelle.
code4life
18

Je veux partager mon expérience avec vous sur cette guerre sans fin: D sur le dilemme clé naturel vs substitut. Je pense que les clés de substitution (artificielles auto-générées) et les clés naturelles (composées de colonnes avec une signification de domaine) ont des avantages et des inconvénients . Donc, selon votre situation, il peut être plus pertinent de choisir une méthode ou une autre.

Comme il semble que beaucoup de gens présentent les clés de substitution comme la solution presque parfaite et les clés naturelles comme la peste, je me concentrerai sur les arguments de l'autre point de vue:

Inconvénients des clés de substitution

Les clés de substitution sont:

  1. Source de problèmes de performances:
    • Ils sont généralement mis en œuvre à l'aide de colonnes auto-incrémentées, ce qui signifie:
      • Un aller-retour vers la base de données chaque fois que vous voulez obtenir un nouvel identifiant (je sais que cela peut être amélioré en utilisant la mise en cache ou des algorithmes similaires à [seq] hilo, mais ces méthodes ont toujours leurs propres inconvénients).
      • Si un jour vous avez besoin de déplacer vos données d'un schéma à un autre (cela arrive assez régulièrement dans mon entreprise au moins), vous risquez de rencontrer des problèmes de collision d'identité. Et oui, je sais que vous pouvez utiliser des UUID, mais ces derniers nécessitent 32 chiffres hexadécimaux! (Si vous vous souciez de la taille de la base de données, cela peut être un problème).
      • Si vous utilisez une séquence pour toutes vos clés de substitution, vous vous retrouverez certainement avec une contention sur votre base de données.
  2. Sujet aux erreurs. Une séquence a une limite max_value donc - en tant que développeur - vous devez faire attention aux points suivants:
    • Vous devez cycle votre séquence (lorsque la valeur max est atteinte, elle revient à 1,2, ...).
    • Si vous utilisez la séquence comme ordre (au fil du temps) de vos données, vous devez gérer le cas du cyclisme (la colonne avec l'ID 1 peut être plus récente que la ligne avec l'ID max-value - 1).
    • Assurez-vous que votre code (et même vos interfaces client qui ne devraient pas se produire car il est supposé être un ID interne) prend en charge les entiers 32b / 64b que vous avez utilisés pour stocker vos valeurs de séquence.
  3. Ils ne garantissent pas des données non dupliquées. Vous pouvez toujours avoir 2 lignes avec toutes les mêmes valeurs de colonne mais avec une valeur générée différente. Pour moi, c'est LE problème des clés de substitution du point de vue de la conception de bases de données.
  4. Plus sur Wikipedia ...

Mythes sur les clés naturelles

  1. Les clés composites sont moins inefficaces que les clés de substitution. Non! Cela dépend du moteur de base de données utilisé:
  2. Les clés naturelles n'existent pas dans la vraie vie. Désolé mais ils existent! Dans l'industrie aéronautique, par exemple, le tuple suivant sera toujours unique par rapport à un vol régulier donné (compagnie aérienne, date de départ, numéro de vol, suffixe opérationnel). Plus généralement, lorsqu'un ensemble de données d'entreprise est garanti comme étant unique par une norme donnée , cet ensemble de données est un [bon] candidat clé naturelle.
  3. Les clés naturelles «polluent le schéma» des tables enfants. Pour moi, c'est plus un sentiment qu'un vrai problème. Avoir une clé primaire de 4 colonnes de 2 octets chacune peut être plus efficace qu'une seule colonne de 11 octets. De plus, les 4 colonnes peuvent être utilisées pour interroger directement la table enfant (en utilisant les 4 colonnes d'une clause where) sans se joindre à la table parent.

Conclusion

Utilisez des clés naturelles lorsqu'il est pertinent de le faire et utilisez des clés de substitution lorsqu'il est préférable de les utiliser.

J'espère que cela a aidé quelqu'un!

mwnsiri
la source
3
Que se passe-t-il lorsque la date de départ du vol prévu est reportée? Devez-vous rechercher toutes les entités associées et supprimer les clés, ou mettez-vous en fait à jour toutes les clés dans les entités associées? Ou avez-vous affaire à une table simple et singulière (peut-être même pas 3NF)?
code4life
Excelent point @ code4life
forcewill
@ code4life: C'est là qu'intervient operationSuffix. Afin de garder le même flightNumber afin d'éviter toute confusion avec le client, nous ajoutons juste un suffixe (par exemple «D»).
mwnsiri le
"Vous pouvez toujours avoir 2 lignes avec toutes les mêmes valeurs de colonne mais avec une valeur générée différente" donc il suffit de mettre une contrainte unique unique ou composite sur vos colonnes.
wha7ever
15

Utilisez toujours une clé qui n'a aucune signification commerciale. C'est juste une bonne pratique.

EDIT: J'essayais de trouver un lien vers celui-ci en ligne, mais je ne pouvais pas. Cependant, dans «Patterns of Enterprise Archtecture» [Fowler], il a une bonne explication de la raison pour laquelle vous ne devriez pas utiliser autre chose qu'une clé sans autre signification que d'être une clé. Cela se résume au fait qu'il ne devrait avoir qu'un seul emploi et un seul emploi.

Titulaire Iain
la source
22
Martin Fowler peut être beaucoup de choses, mais il n'est pas une autorité en matière de conception de bases de données.
Tony Andrews
Je pense que vous devriez fournir un raisonnement avant d'arriver à la conclusion.
Arne Evertsson
4
@ArneEvertsoon La raison est là. «Cela se résume au fait qu'il ne devrait avoir qu'un seul travail et un seul travail. Responsabilité unique.
Iain Holder
10

Les clés de substitution sont très pratiques si vous prévoyez d'utiliser un outil ORM pour gérer / générer vos classes de données. Bien que vous puissiez utiliser des clés composites avec certains des mappeurs les plus avancés (lire: hibernate), cela ajoute une certaine complexité à votre code.

(Bien sûr, les puristes des bases de données soutiendront que même la notion de clé de substitution est une abomination.)

Je suis fan de l'utilisation des uids pour les clés de substitution, le cas échéant. Le principal avantage avec eux est que vous connaissez la clé à l'avance, par exemple, vous pouvez créer une instance d'une classe avec l'ID déjà défini et garanti unique alors qu'avec, par exemple, une clé entière, vous devrez par défaut à 0 ou - 1 et mettez à jour à une valeur appropriée lorsque vous enregistrez / mettez à jour.

Les UID ont des pénalités en termes de recherche et de vitesse de jointure, donc cela dépend de l'application en question pour savoir s'ils sont souhaitables.

Derek Lawless
la source
6

À mon avis, l'utilisation d'une clé de substitution est préférable car il n'y a aucune chance qu'elle change. Presque tout ce que je peux penser et que vous pourriez utiliser comme clé naturelle pourrait changer (avertissement: pas toujours vrai, mais généralement).

Un exemple pourrait être une base de données de voitures - à première vue, vous pourriez penser que la plaque d'immatriculation pourrait être utilisée comme clé. Mais ceux-ci pourraient être modifiés, ce serait donc une mauvaise idée. Vous ne voudriez pas vraiment le savoir après la sortie de l'application, quand quelqu'un vient vous voir pour savoir pourquoi il ne peut pas changer sa plaque d'immatriculation en une nouvelle et brillante personnalisée.

Mark Embling
la source
1
Malheureusement, les voitures ont une clé naturelle qui ne change pas: le VIN (au moins en Amérique ...)
jcollum
@jcollum Oui ok, c'est un bon point. Mon opinion est toujours valable, mon exemple n'était pas nécessairement aussi bon qu'il pourrait l'être.
Mark Embling
2
Une liste de langues serait un exemple de clé naturelle, lorsque vous la basez sur des codes ISO. Donc, si vous souhaitez ensuite charger le contenu d'une table dans une certaine langue, vous n'avez pas besoin de vous joindre à la languagestable car le code de langue (ID) est déjà dans la textstable.
DanMan
@DanMan Je dois être d'accord avec vous. Il y aura toujours des exemples qui fonctionnent mieux avec une clé naturelle. Les règles ou les approches communes ne sont jamais absolues, et c'est un exemple que je
suivrais à
5

Utilisez toujours une seule colonne, clé de substitution si possible. Cela rend les jointures ainsi que les insertions / mises à jour / suppressions beaucoup plus propres, car vous n'êtes responsable que du suivi d'un seul élément d'information pour maintenir l'enregistrement.

Ensuite, si nécessaire, empilez vos clés d'entreprise sous forme de contraintes ou d'index uniques. Cela gardera l'intégrité de vos données intacte.

La logique métier / les clés naturelles peuvent changer, mais la clé physique d'une table ne doit JAMAIS changer.

user7658
la source
4

Dans un scénario d'entrepôt de données, je pense qu'il est préférable de suivre le chemin de la clé de substitution. Deux raisons:

  • Vous êtes indépendant du système source, et les modifications apportées, comme une modification du type de données, ne vous affecteront pas.
  • Votre DW aura besoin de moins d'espace physique puisque vous n'utiliserez que des types de données entiers pour vos clés de substitution. Vos index fonctionneront également mieux.
Santiago Cepas
la source
2

Les clés de substitution peuvent être utiles lorsque les informations commerciales peuvent changer ou être identiques. Les noms commerciaux n'ont pas à être uniques dans tout le pays, après tout. Supposons que vous traitez avec deux entreprises nommées Smith Electronics, une au Kansas et une au Michigan. Vous pouvez les distinguer par adresse, mais cela changera. Même l'État peut changer; Et si Smith Electronics de Kansas City, Kansas traversait la rivière jusqu'à Kansas City, Missouri? Il n'y a pas de moyen évident de garder ces entreprises distinctes avec des informations de clé naturelle, donc une clé de substitution est très utile.

Considérez la clé de substitution comme un numéro ISBN. Habituellement, vous identifiez un livre par titre et auteur. Cependant, j'ai deux livres intitulés "Pearl Harbor" de HP Willmott, et ce sont définitivement des livres différents, pas seulement des éditions différentes. Dans un cas comme celui-là, je pourrais me référer à l'apparence des livres, ou le plus tôt ou le plus tard, mais c'est aussi bien que j'ai l'ISBN sur lequel me rabattre.

David Thornley
la source
1
Je pense que je ne suis pas d'accord avec votre exemple ici. Un numéro ISBN est un attribut d'un livre. Une clé de substitution est indépendante du reste des données de ligne, par conséquent, cette position préconiserait l'utilisation d'une clé de substitution distincte pour une table de livre, même si l'ISBN identifie déjà de manière unique chaque livre.
Christopher Cashell
Sinon, considérez l'ISBN comme une clé de substitution en soi. C'est un identifiant sans signification, juste un code appliqué à un livre spécifique. Si vous créez une table de livres, l'ISBN peut également être la clé primaire (en supposant que vous ayez et aurez toujours un livre par ligne).
David Thornley
@Christopher Cashell - Je suis tombé sur ce post il y a un an mais j'ai pensé ajouter quelque chose. Les ISBN ne sont pas garantis comme étant uniques et peuvent avoir des doublons. J'ai un ami qui a travaillé dans une bibliothèque pendant un certain nombre d'années et qui a souvent rencontré des livres avec des ISBN en double Le problème est que l'unicité de l'ISBN incombe à l'éditeur plutôt qu'à un seul organisme qui garantit que tous les numéros de toutes les publications sont uniques et ces éditeurs n'ont pas toujours agi ensemble.
Thomas
2
Je suis tombé sur ce post il y a un an et je voulais mentionner que les ISBN sont en fait des clés naturelles. Il y a une signification intégrée à la valeur de clé elle-même, contrairement à une clé de substitution. Par exemple, une partie de la clé identifie l'éditeur. De plus, comme je l'ai mentionné ci-dessus, ils ne sont pas garantis d'être uniques. Ils sont censés être uniques mais cette unicité vient des éditeurs et ils n'étaient pas toujours parfaits.
Thomas
Techniquement, les entreprises ne peuvent pas se déplacer entre les États; ce qui se passe, c'est qu'une nouvelle société est créée dans le nouvel état et les actifs sont transférés. Cela fonctionne également pour les informations de base de données.
Warren Dew
2

Pour rappel, il n'est pas recommandé de placer des index clusterisés sur des clés de substitution aléatoires, c'est-à-dire des GUID qui lisent XY8D7-DFD8S, car SQL Server n'a pas la capacité de trier physiquement ces données. Vous devez à la place placer des index uniques sur ces données, bien qu'il puisse également être avantageux d'exécuter simplement le profileur SQL pour les opérations de la table principale, puis de placer ces données dans l'assistant de réglage du moteur de base de données.

Voir le fil de discussion @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be

Bryan Swan
la source
Je suis presque sûr que SQL Server peut trier les GUID.
Michael Green
Ce n'est pas précis, bien qu'ils puissent évaluer le GUID, le tri résultant n'est pas insensé pour un humain. stackoverflow.com/questions/7810602/…
Bryan Swan
1
Une déclaration vraie, mais très différente de "SQL Server n'a pas la capacité de les trier physiquement".
Michael Green
2

Cas 1: votre table est une table de recherche avec moins de 50 types (insertions)

Utilisez des clés professionnelles / naturelles . Par exemple:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Cas 2: votre table est une table avec des milliers d'inserts

Utilisez des clés de substitution / auto-incrémentation . Par exemple:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

Dans le premier cas:

  • Vous pouvez sélectionner tous les programmeurs de la table PEOPLE sans utiliser de jointure avec la table JOB, mais uniquement avec: "SELECT * FROM PEOPLE WHERE JOBCODE = 'PRG'"

Dans le second cas:

  • Vos requêtes de base de données sont plus rapides car votre clé primaire est un entier
  • Vous n'avez pas besoin de vous soucier de trouver la prochaine clé unique car la base de données elle-même vous donne le prochain auto-incrémentation.
Stefanos Kargas
la source
2

C'est l'un de ces cas où une clé de substitution a toujours du sens. Il y a des cas où vous choisissez ce qui est le mieux pour la base de données ou ce qui est le mieux pour votre modèle d'objet, mais dans les deux cas, l'utilisation d'une clé ou d'un GUID sans signification est une meilleure idée. Cela rend l'indexation plus facile et plus rapide, et c'est une identité pour votre objet qui ne change pas.

Charles Graham
la source
1

Cheval pour les cours. Pour déclarer mon parti pris; Je suis d'abord développeur, donc je suis principalement soucieux de donner aux utilisateurs une application fonctionnelle.

J'ai travaillé sur des systèmes avec des clés naturelles et j'ai dû passer beaucoup de temps à m'assurer que les changements de valeur se répercuteraient.

J'ai travaillé sur des systèmes avec uniquement des clés de substitution, et le seul inconvénient est le manque de données dénormalisées pour le partitionnement.

La plupart des développeurs PL / SQL traditionnels avec lesquels j'ai travaillé n'aimaient pas les clés de substitution en raison du nombre de tables par jointure, mais nos bases de données de test et de production n'ont jamais fait peur; les jointures supplémentaires n'affectaient pas les performances de l'application. Avec les dialectes de base de données qui ne prennent pas en charge les clauses telles que "X inner join Y on Xa = Yb", ou les développeurs qui n'utilisent pas cette syntaxe, les jointures supplémentaires pour les clés de substitution rendent les requêtes plus difficiles à lire et plus longues à taper et vérifier: voir le post de @Tony Andrews. Mais si vous utilisez un ORM ou tout autre framework de génération SQL, vous ne le remarquerez pas. La saisie tactile atténue également.

WillC
la source
Aussi; si vous voulez vraiment dire que les clés de substitution ne sont que cela, démarrez-les avec un grand nombre aléatoire et incrémentez les séquences de 3+ plutôt que de 1. Ou utilisez la même séquence pour générer des valeurs pour plus d'une clé.
WillC
1

Peut-être pas tout à fait pertinent pour ce sujet, mais un mal de tête que j'ai face aux clés de substitution. L'analyse pré-livrée d'Oracle crée des SKs générés automatiquement sur toutes ses tables de dimension dans l'entrepôt, et les stocke également sur les faits. Ainsi, chaque fois qu'ils (dimensions) doivent être rechargés au fur et à mesure que de nouvelles colonnes sont ajoutées ou doivent être remplies pour tous les éléments de la dimension, les SK attribués lors de la mise à jour font que les SK ne sont pas synchronisés avec les valeurs d'origine stockées sur le fait, forçant un rechargement complet de toutes les tables de faits qui s'y rattachent. Je préférerais que même si le SK était un nombre sans signification, il y aurait un moyen qu'il ne puisse pas changer pour les disques originaux / anciens. Comme beaucoup le savent, le prêt à l'emploi répond rarement aux besoins d'une organisation et nous devons constamment personnaliser. Nous avons maintenant 3 ans de données dans notre entrepôt, et les recharges complètes à partir des systèmes Oracle Financial sont très importantes. Donc dans mon cas, ils ne sont pas générés à partir de la saisie de données, mais ajoutés dans un entrepôt pour aider à rendre compte des performances. Je comprends, mais les nôtres changent et c'est un cauchemar.

lrb
la source
0

Dans le cas d'une base de données ponctuelle, il est préférable d'avoir une combinaison de clés de substitution et naturelles. Par exemple, vous devez suivre les informations d'un membre pour un club. Certains attributs d'un membre ne changent jamais. par exemple, date de naissance, mais le nom peut changer. Créez donc une table Member avec une clé de substitution member_id et ayez une colonne pour DOB. Créez une autre table appelée nom de la personne et avez des colonnes pour member_id, member_fname, member_lname, date_updated. Dans cette table, la clé naturelle serait member_id + date_updated.


la source