Quelles sont les meilleures pratiques concernant les tables de recherche dans les bases de données relationnelles?

14

Les tables de recherche (ou tables de code , comme certains les appellent) sont généralement une collection des valeurs possibles qui peuvent être données pour une certaine colonne.

Par exemple, supposons que nous ayons une table de recherche appelée party(destinée à stocker des informations sur les partis politiques) qui comporte deux colonnes:

  • party_code_idn, qui contient des valeurs numériques générées par le système et (manquant de sens dans le domaine métier ) fonctionne comme substitut de la clé réelle.
  • party_code, est la clé réelle ou «naturelle» de la table car elle conserve des valeurs qui ont des connotations de domaine métier .

Et disons que ce tableau conserve les données qui suivent:

 +----------------+------------+
 | party_code_idn | party_code |
 +----------------+------------+
 |              1 | Republican |
 |              2 | Democratic |
 +----------------+------------+

La party_codecolonne, qui conserve les valeurs «Républicain» et «Démocratique», étant la véritable clé de la table, est configurée avec une contrainte UNIQUE, mais j'ai facultativement ajouté la party_code_idnet l'ai définie comme PK de la table (bien que, logiquement parlant , party_codepeut fonctionner en tant que CLÉ PRIMAIRE [PK]).

Question

Quelles sont les meilleures pratiques pour pointer vers des valeurs de recherche à partir de tables de transactions ? Dois-je établir des références de CLÉ ÉTRANGÈRE (FK) soit (a) directement à la valeur naturelle et significative ou (b) à des valeurs de substitution?

L' option (a) , par exemple,

 +---------------+------------+---------+
 | candidate_idn | party_code |  city   |
 +---------------+------------+---------+
 |             1 | Democratic | Alaska  |
 |             2 | Republican | Memphis |
 +---------------+------------+---------+

a les propriétés suivantes 1 :

  1. Lisible pour l'utilisateur final (+)
  2. Facile à importer-exporter à travers les systèmes (+)
  3. Difficile de changer la valeur car elle doit être modifiée dans tous les tableaux référents (-)
  4. L'ajout de nouvelle valeur n'est pas coûteux (=)

Je pense que c'est presque comme « passer par la valeur », pour tirer une analogie de l'appel de fonction dans le jargon de programmation d'application.

L'option (b) , par exemple,

 +---------------+----------------+---------+
 | candidate_idn | party_code_idn |  city   |
 +---------------+----------------+---------+
 |             1 |              1 | Alaska  |
 |             2 |              2 | Memphis |
 +---------------+----------------+---------+

a les propriétés ci-dessous:

  1. Non lisible pour l'utilisateur final (-)
  2. Difficile d' importer-exporter car il faut le dé-référencer (-)
  3. Changement facile des valeurs, car nous stockons uniquement les références dans les tables de transactions (+)
  4. L'ajout de nouvelle valeur n'est pas coûteux (=)

Il est très similaire à « passer par référence », si on le compare à l'appel de fonction dans le langage de programmation d'application.

Import-export peut également être fait d'une manière différente, à savoir, tout en alimentant la table de consultation à nouveau puis réensemencer la colonne de substitution. J'espère que je comprends bien, c'est quelque chose que je viens d'entendre comme une possibilité.

1. Notez que +, -et =indiquer l'avantage de ces propriétés.

Question

Assez important: y a-t-il une différence entre une table de recherche (ou code ) et une référence FK si nous voulons simplement utiliser cette dernière approche? Je pense qu'ils fonctionnent tout de même.

Ressources associées

Nishant
la source

Réponses:

10

Par IDN, je suppose que vous voulez dire un IDENTITY, SEQUENCEou le AUTO_INCREMENTterrain? Vous devriez jeter un œil ici et ici .

Remarque, section 5 (Utilisation abusive des valeurs de données en tant qu'éléments de données) de la première référence, sous la figure 10

Bien sûr, vous pouvez avoir une table distincte pour les vendeurs, puis la référencer en utilisant une clé étrangère, de préférence avec une simple clé de substitution telle que sales_person_id, comme indiqué ci-dessus.

Ainsi, cet expert pense que vous devez "déférer" les clés de substitution. C'est vraiment une technique SQL de base et ne devrait pas causer de problèmes dans votre SQL quotidien. Il semble qu'il y ait une erreur dans la figure 10 - le commercial dans SalesData doit être une clé de substitution (c'est-à-dire un nombre), pas du texte. Je déduis cela de la citation ci-dessus.

Ce que vous devez éviter à tout prix est la tentation (très courante pour les programmeurs de bases de données novices) de commettre l'erreur décrite dans la section (1) Tables de recherche communes. Ceci est communément appelé l'approche MUCK ( Massively Unified Code Key ) (pas par accident :-) notamment par Joe Celko , également connu sous le nom sarcastique de l' OTLT - One True Lookup Table ) et conduit à toutes sortes de difficultés. Les programmeurs débutants semblent estimer qu'une seule table de code / recherche / autre est "plus propre" et sera plus efficace quand rien ne pourrait être plus éloigné de la vérité.

De la deuxième référence ci-dessus:

La normalisation élimine les données redondantes, ce qui simplifie considérablement la tâche d'application de l'intégrité des données, mais le processus de création d'un MUCK est une tout autre chose. comme je vais le démontrer, moins de tableaux n'est pas synonyme de simplicité.

Vous voudrez peut-être également jeter un œil au paradigme EAV ( Entity Attribute Value ) connexe que je traite ici .

Vérace
la source
Par IDN, je voulais dire la clé étrangère générée automatiquement. Je n'utilise pas les tables de recherche communes, vous ne savez pas comment vous pensiez que j'utilisais cela? Nous utilisons en fait des centaines de tables de code. Il semble vraiment étrange que quelqu'un fasse cela dans une table unifiée. Mais il est bon de savoir qu'un tel modèle existe et doit être évité. EAV semble intéressant. Donc, le consensus est que je devrais déréférencer en utilisant IDN, c'est-à-dire la clé de substitution?
Nishant
1
Le stratagème de "déréférencement" semble certainement être l'approche majoritaire. Pourquoi ne pas expérimenter un peu et voir comment vous vous en sortez? Choisissez des clés naturelles et voyez comment fonctionne votre SQL - puis spécifiez un substitut et essayez-le pendant un moment. Celko et Pascal seraient respectés dans le monde SQL / relationnel, mais j'ai vu des gens se disputer avec eux en disant que leur approche était trop doctrinaire et puriste - et que les systèmes "réels" devaient utiliser des clés de substitution. Si votre clé naturelle est FOREIGN KEYcomposée de trois champs et que cela se trouve en outre dans une autre table, cela peut devenir assez compliqué mais YMMV.
Vérace
Ouais, j'ai eu cette pensée puriste et je me demandais pourquoi les gens utilisent des clés de substitution! Et puis certains cas d'utilisation semblaient vraiment difficiles à gérer dans le monde puriste. Je pensais que l'approche de substitution était plus facile, bien que vous ayez certains inconvénients à importer et exporter. En effet, le scénario de combinaison peut être plus délicat. Les tables de code Btw ne sont pas très différentes de la clé étrangère dans le scénario de substitution, n'est-ce pas? Je veux dire que la distinction logique existe mais ce n'est rien d'autre qu'une clé étrangère.
Nishant
1
Vous pouvez appliquer vos clés naturelles via UNIQUE CONSTRAINTs et NOT NULLs - eh bien, vos entrées de table de code sont FOREIGN KEYs dans les tables qui les utilisent / s'y réfèrent - donc les concepts sont liés, mais pas les mêmes. La clé de substitution de la table de codes est le champ qui apparaît dans la table "enfant" - moins lisible certes, mais INTpas très grand - pas beaucoup d'espace requis, ce qui est un avantage des clés de substitution.
Vérace
10

Il existe une troisième approche qui présente certains des avantages de vos deux options - mettre un code réel dans la table de code. J'entends par là une courte séquence de caractères qui capture l'essence de la pleine valeur et est unique. Pour votre exemple donné, il peut être

Idn: 1
Name: Democrats
Code: D      (or DEM)

Le code est transposé dans les tables transactionnelles comme une clé étrangère. Elle est courte, intelligible et quelque peu indépendante des données "réelles". Des modifications incrémentielles du nom ne suggéreraient pas de changement de code. Si les républicains décampaient en masse , cependant, un changement de code pourrait être nécessaire, avec les problèmes qui en découlent qu'un identifiant de substitution ne serait pas encouru.

Ce style a été appelé codage d'abréviations. Je peux recommander l'écriture de Celko à ce sujet. Google books en contient plusieurs exemples. Recherchez "Codage Celko".

Autres exemples: encodages à 2 ou 3 lettres pour les pays, encodage à 3 lettres (GBP, USD, EUR) pour les codes de devise. Court, explicite et ne change pas (et il y a un ISO pour eux).

Michael Green
la source