Garder une énumération et une table synchronisées

11

Je crée un programme qui publiera des données dans une base de données, et je suis tombé sur un modèle que je suis sûr de connaître: un petit tableau des valeurs fixes les plus probables (très fortement probables) qui servent d'énumération. Supposons donc le tableau suivant appelé Status:

  Statut
  Description de l'ID
  --------------
   0 non traité
   1 En attente
   2 traités
   3 Erreur

Dans mon programme, je dois déterminer un ID d'état pour une autre table, ou éventuellement mettre à jour un enregistrement avec un nouvel ID d'état.

Je pourrais coder en dur les statuts dans une énumération et j'espère que personne ne changera jamais la base de données. Ou je pourrais précharger les valeurs en fonction de la description (hardcoding ainsi que la place).

Quelle serait la bonne approche pour garder ces deux, enum et table, synchronisés?

MPelletier
la source
Pourquoi gardez-vous les choses synchronisées et non synchronisées? Synch (dis-le) est bizarre!
MrFox
1
@suslik Ils sont tous deux prononcés de la même façon. Synch et Sync .
MPelletier
1
Avoir une énumération et la table de base de données est une duplication. À moins que la table de base de données ne soit utilisée par d'autres applications, je renoncerais à la table et utiliserais simplement l'énumération. Si la table sera utilisée dans plusieurs applications, chargez plutôt les statuts à partir de la base de données lors de l'exécution.
Peter Smith
Ça dépend du contexte. Dans ce cas, étant des valeurs de statut de workflow ou de tâche, j'aurais tendance à préférer les garder plus dynamiques que statiques, car les processus ont souvent tendance à changer; et ont tendance à changer de bande pour les calendriers de sortie des logiciels. D'un autre côté, si c'est un service stable qui a peu de chances d'avoir de nouveaux états introduits ou des états existants supprimés, je serais peut-être plus obligé de coder en dur l'enum / les dénormaliser (selon la façon dont les enregistrements sont utilisés plus tard).
JustinC
@PeterSmith La base de données ne peut pas appliquer de contraintes si elles se trouvent uniquement dans votre énumération Java et non dans une table. Vous allez contraindre des valeurs dans votre base de données, n'est-ce pas?
David Conrad

Réponses:

5

Je coderais en dur l'énumération dans votre programme, car je soupçonne que ces différents statuts affectent la logique de vos programmes. Si vous avez un nouveau statut, comment votre programme est-il censé réagir à ce nouveau statut?

Parce que la base de données fait partie de votre application, je ne pense pas qu'il serait logique d'affecter l'une sans consulter l'autre, en quelque sorte.

Matthieu
la source
Il ne s'agit pas tant de nouveaux statuts (qui justifieraient certainement une modification de la base de données et du programme), mais des valeurs d'ID.
MPelletier
2
Je ne vois pas pourquoi vous changeriez la valeur d'ID sans changer sa signification. Ce type d'énumérations ne serait pas incrémenté automatiquement, et ce n'est vraiment que pour la lisibilité pour les personnes qui déboguent la base de données, car généralement votre application fera des requêtes et elle connaîtra déjà l'ID pending. Bien sûr, avoir une Statustable vous donne l'intégrité référentielle, mais c'est le point que j'essaie de faire valoir.
Matthew
Eh bien oui, c'est l'idée. Mais si je mets les ID à un endroit et à d'autres, je pars du principe qu'ils ont tous les deux raison. C'est un lien lâche, non?
MPelletier
3
Nous faisons ces hypothèses tout le temps, si vous pensez à une définition de table, notre programme suppose que la définition est comme telle lors de l'écriture d'une requête. Le Statustableau ne doit pas être considéré comme dynamique pendant l'exécution de l'application, et donc je ne pense pas que vous devriez le lire comme tel.
Matthew
8

Je charge normalement ces données dans un cache statique (généralement dans un HashMap ou quelque chose comme ça) lorsque l'application démarre. Cela évite d'avoir à recompiler juste parce que l'énumération a été modifiée d'une manière ou d'une autre.

FrustratedWithFormsDesigner
la source
2

Parce que ce sont des statuts, ils doivent être codés en dur dans l'application pour garantir qu'aucun changement de base de données ne corrompra votre programme (du moins pas facilement). Ceci est important car chaque état qui doit être ajouté doit d'abord être codé et non simplement ajouté à la base de données.

Vous devriez toujours avoir ces valeurs d'état écrites dans la base de données avec leurs descriptions correctes au cas où vous auriez besoin de générer un rapport par exemple.

Habituellement, j'ai un petit extrait de code qui se connecte à la base de données et vérifie que les statuts répertoriés dans un tableau spécifique ont tous les mêmes valeurs d'ID / nom que j'ai codées en dur en mémoire. S'ils ne correspondent pas, j'arrêterai l'exécution du logiciel.

En fonction de vos besoins, vous souhaiterez peut-être implémenter des comportements légèrement différents, mais dans l'ensemble, c'est une bonne idée d'avoir ces statuts codés en dur de toute façon.

Alex
la source
2

Nous avons des problèmes similaires sur mon projet (code hérité, hourra!) Le problème majeur est que "les tables d'énumération ne changent jamais" jusqu'à ce qu'elles le fassent et que le code se casse. J'ai deux stratégies pour atténuer ma migration lente vers.

Le premier et le meilleur consiste à éliminer les références directes à ces valeurs dans la mesure du possible. Demandez toujours "pourquoi dois-je utiliser directement la valeur énumérée?" Dans de nombreux cas, cela indique que le code contient trop d'hypothèses codées en dur ou essaie de faire trop de manipulations sur les données. Vérifiez si vous ne pouvez pas établir de meilleures relations dans la base de données ou un code plus flexible pour gérer ce qui est manipulé.

Lorsque cela ne fonctionne pas, je passe au plan B: génération de code. Étant donné que les tables changent rarement et que nous publions régulièrement de nouvelles versions, un générateur de code peut lire les tables d'énumération et écrire le code d'énumération. Cette bibliothèque générée dynamiquement est ensuite utilisée dans le projet. Si la base de données change, la prochaine génération ne sera pas compilée, ce qui est bien mieux que d'obtenir des erreurs d'exécution mystérieuses.

CodexArcanum
la source
Comment élimineriez-vous les références à une énumération? Par exemple, vous triez ou recherchez par statut dans ce cas. Avoir une certaine valeur magique dans la DB ne me convient pas non plus. C'est à cela que servent les tables de recherche.
nportelli
Dans le passé, j'ai fait le contraire. Chaque fois qu'il y a un changement de code dans Enum, au démarrage de l'application, il synchronise ces valeurs avec la base de données. Ici, le code est la source de la vérité. La base de données en est une représentation. En général, j'ignore les valeurs dans DB que le code ne peut pas comprendre, mais de cette façon, j'obtiens un mécanisme pour nettoyer automatiquement DB si nécessaire.
Anshul