J'ai vu un certain nombre de questions, comme celle-ci , demandant des conseils sur la manière de stocker des énumérations dans DB. Mais je me demande pourquoi tu ferais ça. Alors disons que j'ai une entité Person
avec un gender
champ et un Gender
enum. Ensuite, ma table de personnes a un genre de colonne.
Outre la raison évidente de l'exactitude, je ne vois pas pourquoi je créerais une table supplémentaire gender
pour cartographier ce que j'ai déjà dans ma candidature. Et je n'aime pas vraiment avoir cette duplication.
Réponses:
Prenons un autre exemple moins chargé de conceptions et d’attentes. J'ai un enum ici, et c'est l'ensemble des priorités pour un bogue.
Quelle valeur stockez-vous dans la base de données?
Donc, je pourrais être le stockage
'C'
,'H'
,'M'
et'L'
dans la base de données. Ou'HIGH'
etc. Cela pose le problème des données fortement typées . Il existe un ensemble connu de valeurs valides, et si vous ne stockez pas cet ensemble dans la base de données, il peut être difficile de travailler avec.Pourquoi stockez-vous les données dans le code?
Vous avez
List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
ou quelque chose à cet effet dans le code. Cela signifie que vous disposez de plusieurs mappages de ces données vers le format approprié (vous insérez des majuscules dans la base de données, mais vous les affichez commeCritical
). Votre code est maintenant aussi difficile à localiser. Vous avez lié la représentation de l'idée à la base de données à une chaîne stockée dans le code.Partout où vous avez besoin d'accéder à cette liste, vous devez avoir une duplication de code ou une classe avec un groupe de constantes. Ni de ce qui sont de bonnes options. Il ne faut pas oublier non plus que d’ autres applications peuvent utiliser ces données (qui peuvent être écrites dans d’autres langages - l’application Web Java utilise un système de génération de rapports Crystal Reports et un travail par lots Perl y introduisant des données). Le moteur de génération de rapports doit connaître la liste de données valides (que se passe-t-il s'il n'y a rien de
'LOW'
prioritaire et que vous devez savoir qu'il s'agit d'une priorité valide pour le rapport?), Et le travail par lots contiendrait les informations valides. les valeurs sont.De manière hypothétique, vous pourriez dire "nous sommes une boutique mono-langue - tout est écrit en Java" et ne posséder qu'un seul fichier .jar contenant ces informations - mais cela signifie désormais que vos applications sont étroitement liées les unes aux autres et que .jar contient les données. Vous devrez publier la partie création de rapports et la partie mise à jour par lot, ainsi que l'application Web, à chaque modification - et espérez que cette publication se déroule sans problème pour toutes les parties.
Que se passe-t-il lorsque votre patron souhaite une autre priorité?
Votre patron est venu aujourd'hui. Il y a une nouvelle priorité -
CEO
. Maintenant, vous devez modifier tout le code , recompiler et redéployer.Avec une approche 'enum-in-the-table', vous mettez à jour la liste enum afin de définir une nouvelle priorité. Tout le code qui obtient la liste la extrait de la base de données.
Les données sont rarement seules
Avec les priorités, les clés de données dans d' autres tables peuvent contenir des informations sur les flux de travail ou indiquer qui peut définir cette priorité ou non.
Revenons un peu au genre mentionné dans la question: le genre a un lien avec les pronoms utilisés:
he/his/him
etshe/hers/her
... et vous voulez éviter de le coder en dur dans le code lui-même. Et ensuite, votre patron passe et vous devez ajouter que vous avez le'OTHER'
genre (pour que ce soit simple) et vous devez associer ce genre àthey/their/them
... et votre patron voit ce que Facebook a et ... eh bien, oui.En vous limitant à un bit de données fortement typé plutôt qu’à une table d’énumération, vous devez maintenant répliquer cette chaîne dans un tas d’autres tables afin de conserver cette relation entre les données et ses autres bits.
Qu'en est-il des autres magasins de données?
Peu importe où vous stockez cela, le même principe existe.
priorities.prop
qui a la liste des priorités. Vous lisez cette liste à partir d'un fichier de propriétés.Vous pouvez avoir une base de données de magasin de documents (telle que CouchDB ) ayant une entrée pour
enums
(puis écrire une fonction de validation en JavaScript ):Vous pourriez avoir un fichier XML avec un peu d'un schéma:
L'idée de base est la même. Le magasin de données lui-même est l'endroit où la liste des valeurs valides doit être stockée et appliquée. En le plaçant ici, il est plus facile de raisonner sur le code et les données. Vous n'avez pas à vous soucier de vérifier de façon défensive ce que vous avez à chaque fois (majuscule ou minuscule? Pourquoi y a-t-il un
chritical
type dans cette colonne? Etc ...) parce que vous savez ce que vous récupérez du datastore exactement ce que le magasin de données s'attend à ce que vous l'envoyiez autrement - et vous pouvez lui demander une liste de valeurs valides.La livraison
L'ensemble des valeurs valides sont des données , pas du code. Vous ne devez lutter pour DRY le code - mais la question de la duplication est que vous dupliquez les données dans le code, plutôt que de respecter sa place en tant que données et le stocker dans une base de données.
Cela facilite l'écriture de plusieurs applications sur le magasin de données et évite d'avoir des instances dans lesquelles vous devrez déployer tout ce qui est étroitement couplé aux données, car vous n'avez pas couplé votre code aux données.
Cela facilite le test des applications, car vous n'avez pas à retester l'intégralité de l'application lorsque la
CEO
priorité est ajoutée, car vous ne disposez d'aucun code qui se soucie de la valeur réelle de la priorité.Le fait de pouvoir raisonner le code et les données indépendamment les uns des autres facilite la recherche et la correction des bogues lors de la maintenance.
la source
Selon vous, laquelle de ces erreurs est la plus susceptible de produire des erreurs lors de la lecture de la requête?
Ou
Les gens fabriquent des tables d'énumération en SQL car ils trouvent que ces dernières sont plus lisibles, ce qui réduit le nombre d'erreurs lors de l'écriture et de la maintenance de SQL.
Vous pourriez faire du genre une chaîne directement dans
Person
, mais vous devrez alors essayer de faire valoir le cas. Vous pouvez également augmenter le temps de stockage de la table et le temps d'interrogation en raison de la différence entre les chaînes et les entiers, en fonction de la puissance de votre base de données en termes d'optimisation.la source
Je ne peux pas croire que les gens n'en aient pas encore parlé.
Clés étrangères
En conservant l'énumération dans votre base de données et en ajoutant une clé étrangère à la table contenant une valeur enum, vous vous assurez qu'aucun code n'entre jamais de valeurs incorrectes pour cette colonne. Cela contribue à l'intégrité de vos données et constitue la raison la plus évidente pour vous, OMI, de disposer de tableaux pour les énumérations.
la source
Je suis dans le camp qui est d'accord avec toi. Si vous conservez une énumération de genre dans votre code et un tblGender dans votre base de données, vous risquez de rencontrer des difficultés lors de la maintenance. Vous aurez besoin de documenter que ces deux entités doivent avoir les mêmes valeurs et donc toutes les modifications que vous apportez à l'une que vous devez également apporter à l'autre.
Vous devrez ensuite transmettre les valeurs enum à vos procédures stockées, comme suit:
Mais imaginez ce que vous feriez si vous gardiez ces valeurs dans une table de base de données:
Certaines bases de données relationnelles sont construites avec des jointures en tête, mais quelle requête est la plus facile à lire?
Voici un autre exemple de requête:
Comparez cela à ceci:
Voici encore un autre exemple de requête:
Notez que dans cet exemple, vous devez convertir la cellule de genre dans vos résultats d'un entier en un enum. Ces conversions sont faciles cependant. Comparez cela à ceci:
Toutes ces requêtes sont plus petites et plus faciles à gérer avec votre idée de conserver les définitions d’énum dans la base de données.
la source
Je créerais une table de genre car elle peut être utilisée dans l'analyse de données. Je pourrais rechercher toutes les personnes de sexe masculin ou féminin dans la base de données pour générer un rapport. Plus vous pourrez visualiser vos données, plus il sera facile de découvrir des informations de tendance. Évidemment, il s’agit d’une énumération très simple, mais pour les énumérations complexes (comme les pays du monde ou les États), il est plus facile de générer des rapports spécialisés.
la source
Tout d'abord, vous devez décider si la base de données ne sera jamais utilisée que par une seule application ou s'il est possible que plusieurs applications l'utilisent. Dans certains cas, une base de données n'est rien de plus qu'un format de fichier pour une application (les bases de données SQLite peuvent souvent être utilisées à cet égard). Dans ce cas, dupliquer un peu la définition de l'énumération en tant que table peut souvent suffire et donner plus de sens.
Cependant, dès que vous envisagez la possibilité d'avoir plusieurs applications accédant à la base de données, alors une table pour l'énumération a beaucoup de sens (les autres réponses expliquent pourquoi plus en détail). L'autre élément à prendre en compte est-ce que vous ou un autre développeur souhaitez examiner les données de base de données brutes. Si tel est le cas, cela peut être considéré comme une autre utilisation d’application (une seule où la jauge de laboratoire est du SQL brut).
Si vous avez l'énumération définie dans le code (pour un code plus propre et une vérification de la compilation) ainsi qu'un tableau dans la base de données, je vous recommanderais d'ajouter des tests unitaires pour vérifier que les deux sont synchronisés.
la source
Lorsque vous avez une énumération de code utilisée pour gérer la logique applicative dans le code, vous devez toujours créer une table pour représenter les données dans la base de données pour les nombreuses raisons détaillées ci-dessus / ci-dessous. Voici quelques conseils pour vous assurer que vos valeurs de base de données restent synchronisées avec les valeurs de code:
Ne transformez pas le champ ID de la table en colonne Identity. Inclure l'ID et la description en tant que champs.
Faites quelque chose de différent dans la table pour aider les développeurs à savoir que les valeurs sont semi-statiques / liées à une énumération de code. Dans toutes les autres tables de recherche (généralement où des valeurs peuvent être ajoutées par les utilisateurs), j'ai généralement LastChangedDateTime et LastChangedBy, mais ne pas les avoir sur des tables enum liées m'aide à me rappeler qu'elles ne sont modifiables que par les développeurs. Documentez ceci.
Créez un code de vérification qui vérifie que chaque valeur de l'énumération figure dans la table correspondante et que seules ces valeurs figurent dans la table correspondante. Si vous avez des "tests de santé" d'application automatisés qui s'exécutent après la construction, accédez-y. Sinon, exécutez le code automatiquement au démarrage de l'application chaque fois que l'application s'exécute dans l'EDI.
Créez des scripts SQL de production qui font la même chose, mais à partir de la base de données. Si elles sont créées correctement, elles contribueront également aux migrations d'environnement.
la source
Cela dépend aussi de qui accède aux données. Si vous avez juste une application, ça pourrait aller. Si vous ajoutez un entrepôt de données ou un système de reporting. Ils auront besoin de savoir ce que ce code signifie, quelle est la version redable humaine du code.
Généralement, la table de types ne serait pas dupliquée en tant qu'énum dans le code. Vous pouvez charger la table de types dans une liste mise en cache.
Souvent, le type va et vient. Vous aurez besoin d'une date pour le moment où le nouveau type a été ajouté. Savoir quand un type spécifique a été supprimé. Affichez-le uniquement lorsque cela est nécessaire. Que faire si un client veut "transgenre" en tant que genre mais que les autres clients ne le veulent pas? Toutes ces informations sont mieux stockées dans la base de données.
la source