Clés étrangères - lien à l'aide d'une clé de substitution ou d'une clé naturelle?


14

Existe-t-il une meilleure pratique pour savoir si une clé étrangère entre les tables doit être liée à une clé naturelle ou à une clé de substitution? La seule discussion que j'ai vraiment trouvée (à moins que mon google-fu manque) est la réponse de Jack Douglas dans cette question , et son raisonnement me semble solide. Je suis au courant de la discussion au-delà du fait que les règles changent, mais ce serait quelque chose qui devrait être pris en considération dans n'importe quelle situation.

La principale raison de la demande est que j'ai une application héritée qui utilise des FK avec des clés naturelles, mais il y a une forte poussée des devlopers pour passer à un OR / M (NHibernate dans notre cas), et une fourche a déjà produit certains Je suis en train de les repousser sur la bonne voie à l'aide de la clé naturelle ou de déplacer l'application héritée pour utiliser des clés de substitution pour le FK. Mon instinct dit de restaurer le FK d'origine, mais je ne suis vraiment pas sûr que ce soit vraiment la bonne voie à suivre.

La majorité de nos tables ont déjà à la fois une clé de substitution et une clé naturelle déjà définies (bien que la contrainte unique et PK), donc avoir à ajouter des colonnes supplémentaires n'est pas un problème pour nous dans cette perspective. Nous utilisons SQL Server 2008, mais j'espère que c'est assez générique pour n'importe quelle base de données.

Réponses:


15

Ni SQL ni le modèle relationnel ne sont perturbés par des clés étrangères qui référencent une clé naturelle. En fait, le référencement de clés naturelles améliore souvent considérablement les performances. Vous seriez surpris de voir combien de fois les informations dont vous avez besoin sont complètement contenues dans une clé naturelle; référencer cette clé échange une jointure pour une table plus large (et réduit par conséquent le nombre de lignes que vous pouvez stocker sur une page).

Par définition, les informations dont vous avez besoin sont toujours entièrement contenues dans la clé naturelle de chaque table de "recherche". (Le terme table de recherche est informel. Dans le modèle relationnel, toutes les tables ne sont que des tables. Une table de codes postaux américains peut avoir des lignes qui ressemblent à ceci: {AK, Alaska}, {AL, Alabama}, {AZ, Arizona} , etc. La plupart des gens appellent cela une table de recherche.)

Sur les grands systèmes, il n'est pas rare de trouver des tables qui ont plus d'une clé candidate. Il n'est pas rare non plus que les tables qui servent à une partie de l'entreprise à référencer une clé candidate et les tables qui servent à une autre partie de l'entreprise à référencer une clé candidate différente. C'est l'un des points forts du modèle relationnel, et il fait partie du modèle relationnel que SQL supporte assez bien.

Vous rencontrerez deux problèmes lorsque vous référencerez des clés naturelles dans des tables qui ont également une clé de substitution.

Tout d'abord, vous surprendrez les gens. Bien que je fasse habituellement du lobbying pour le principe de la moindre surprise je fasse , c'est une situation où je ne me dérange pas de surprendre les gens. Lorsque le problème est que les développeurs sont surpris par l'utilisation logique des clés étrangères, la solution est l'éducation, pas la refonte.

Deuxièmement, les ORM ne sont généralement pas conçus autour du modèle relationnel, et ils incarnent parfois des hypothèses qui ne reflètent pas les meilleures pratiques. (En fait, ils semblent souvent avoir été conçus sans jamais avoir à faire appel à un professionnel de la base de données.) Exiger un numéro d'identification dans chaque table est l'une de ces hypothèses. Un autre suppose que l'application ORM "possède" la base de données. (Il est donc gratuit de créer, supprimer et renommer des tables et des colonnes.)

J'ai travaillé sur un système de base de données qui a servi des données à des centaines de programmes d'application écrits dans au moins deux douzaines de langues sur une période de 30 ans. Cette base de données appartient à l'entreprise et non à un ORM.

Une fourchette qui introduit des changements de rupture devrait être un arrêtoir.

J'ai mesuré les performances avec des clés naturelles et des clés de substitution dans une entreprise où je travaillais. Il y a un point de basculement où les clés de substitution commencent à surpasser les clés naturelles. ( En supposant qu'aucun supplémentaire effort nécessaire pour maintenir les performances des clés naturelles à un niveau élevé, comme le partitionnement, les index partiels, les index basés sur les fonctions, les espaces de table supplémentaires, l'utilisation de disques SSD, etc.) D'après mes estimations pour cette société, ils atteindront ce point de basculement dans vers 2045. En attendant, ils obtiennent de meilleures performances avec des touches naturelles.

Autres réponses pertinentes: Dans le schéma de la base de données Confus


5

La principale raison pour laquelle je supporte les clés de substitution est que les clés naturelles sont souvent sujettes à changement et cela signifie que toutes les tables associées doivent être mises à jour, ce qui peut mettre une charge considérable sur le serveur.

En outre, au cours des 30 dernières années, j'ai utilisé une variété de bases de données sur de nombreux sujets, la véritable clé naturelle est souvent assez rare. Les choses sont censées être uniques (SSN) ne le sont pas, les choses qui sont uniques à un moment donné peuvent devenir non uniques plus tard et certaines choses comme les adresses e-mail et les numéros de téléphone peuvent être uniques, mais elles peuvent être réutilisées pour différentes personnes à une date ultérieure Date. Bien sûr, certaines choses n'ont tout simplement pas un bon identifiant unique comme les noms de personnes et de sociétés.

Quant à éviter les jointures en utilisant une clé naturelle. Oui, cela peut accélérer les instructions select qui n'ont pas besoin des jointures, mais cela ralentira les endroits où vous avez toujours besoin des jointures car les jointures int sont généralement plus rapides. Cela ralentira également probablement les insertions et les suppressions et entraînera des problèmes de performances sur les mises à jour lorsque la clé changera. Les requêtes complexes (qui sont de toute façon plus lentes) seront encore plus lentes. Les requêtes simples sont donc plus rapides, mais les rapports et les requêtes complexes et de nombreuses actions contre la base de données peuvent être plus lents. Il s'agit d'un équilibre, qui peut basculer dans un sens ou dans l'autre selon la façon dont votre base de données est interrogée.

Il n'y a donc pas de réponse unique. Cela dépend de votre base de données, de la façon dont elle sera interrogée et du type d'informations qui y sont stockées. Vous devrez peut-être effectuer des tests pour découvrir ce qui fonctionne le mieux dans votre propre environnement.


1
"... les clés naturelles sont souvent sujettes à changement ..." - alors ce ne sont pas de très bonnes clés! Si un attribut change souvent, ne l'utilisez pas comme clé (pour diverses définitions de "souvent", bien sûr). Fabian Pascal a fait valoir qu'il y a quatre critères pour choisir une clé: la familiarité, l'irréductibilité, la stabilité et la simplicité. Parfois, vous les échangez pour la simplicité d'une clé de substitution. Comme l'a dit HLGEM, "Il n'y a donc pas de réponse universelle".
Greenstone Walker

1
@GreenstoneWalker, je conviens que vous ne devriez pas le proposer comme clé alors, mais souvent vous n'avez pas de clé qui correspond aux quatre critères et vous devez aller avec ce qui est unique. Et lorsque l'unicité est une clé copmposite, le problème peut être encore plus important en termes de performances lorsque vous devez avoir les jointures.
HLGEM

-4

Si vous ne connaissez pas la réponse, optez pour la mère porteuse. Voici pourquoi - si des hypothèses sont émises sur les règles métier et que ces hypothèses sont fausses ou que les règles changent, vos données sont des ordures. Voici un exemple:

Personne, Rôle, PersonRole

la règle commerciale actuelle stipule qu'une personne a un rôle. Vous créez un tableau qui relie Personne et Rôle où PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)

Maintenant, vous êtes un vrai puriste en ce qui concerne les clés naturelles! Mais sérieusement, que se passe-t-il si l'organisation décide qu'une personne peut désormais assumer plusieurs rôles? Quels sont les effets en aval de l'accompagnement de l'évolution des besoins de l'entreprise?


2
Et vous n'avez pas ces problèmes avec les clés de substitution? Veuillez nous montrer comment.
Colin 't Hart

4
L'exemple donné ne semble rien démontrer de pertinent pour la discussion.
mustaccio
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.