Meilleures pratiques: Stocker l'état d'un flux de travail d'un élément dans une base de données?

StackOverflow https://stackoverflow.com/questions/116762

Question

J'ai une question sur les meilleures pratiques en matière de stockage des états de flux de travail complexes pour le traitement des tâches dans une base de données. J'ai cherché en ligne sans résultat, alors j'ai pensé demander à la communauté ce qu'elle pensait être le meilleur.

Cette question provient du même "BoxItem". exemple j'ai donné dans une question précédente. Ce " BoxItem " est suivi dans mon système à mesure que diverses tâches sont effectuées sur celui-ci. La tâche peut se dérouler sur plusieurs jours et avec une interaction humaine. Par conséquent, l'état du BoxItem doit être conservé. Qui a effectué la tâche (le cas échéant) et quand la tâche a été effectuée doit également faire l'objet d'un suivi.

Au début, j’ai abordé cette question en ajoutant trois champs au champ "BoxItems". table pour chaque tâche interactive humaine qui doit être effectuée:

Est-ce que Nom de la tâche est terminé

Date Nom de la tâche terminée

Utilisateur Nom de la tâche Terminé

Cela fonctionnait lorsque le flux de travail était simple ... mais maintenant qu'il est devenu un processus complexe (> 10 interactions humaines possibles dans le flux ... environ la moitié d'entre elles sont facultatives et peuvent ou ne peuvent pas être effectuées pour BoxItem, ce qui m'a amené à ajouter des champs "Do TaskName " ainsi que pour les tâches facultatives), j'ai constaté que ce qui aurait dû être un simple tableau en contient maintenant 40 ou plus. donc champ entièrement consacré à la conservation de cette information d'état.

Je me demande s'il n'y a pas de meilleure façon de le faire ... mais je suis perdue.

Ma première pensée a été de créer un "BoxItemTasks" générique. tableau qui définit les tâches pouvant être effectuées sur une boîte donnée, mais il me faudrait tout de même enregistrer les informations de date et d'utilisateur individuellement, de sorte que cela n'aide pas vraiment.

Ma deuxième pensée a été que cela importait peut-être, et je ne devrais pas m'inquiéter si cette table contient 40 champs ou plus consacrés à la conservation d'état ... et peut-être que je suis juste paranoïaque. Mais c’est comme si c’était beaucoup d’informations à conserver.

Quoi qu'il en soit, je ne sais pas ce que pourrait être une troisième option, ou si l’une des deux options ci-dessus est réellement raisonnable. Je peux voir que ce flux de travail est susceptible de devenir encore plus complexe à l'avenir, et pour chaque nouvelle tâche, je devrai ajouter 3 ou 4 champs juste pour faciliter le suivi ... on a l'impression qu'il est en train de devenir incontrôlable.

Que feriez-vous dans cette situation?

Je dois noter qu'il s'agit de la maintenance d'un système existant, un système qui a été construit sans ORM, je ne peux donc pas laisser cela à l'ORM de s'en charger.

EDIT:

Kev, parlez-vous de faire quelque chose comme ceci:

Articles de boîte

(PK) BoxItemID

(Autres objets non pertinents)

BoxItemActions

(PK) BoxItemID

(PK) BoxItemTaskID

est terminé

Date d'achèvement

Utilisateur terminé

BoxItemTasks

Type de tâche (PK)

Description (si nécessaire)

Hmm ... cela fonctionnerait ... cela représenterait un besoin de changer l'approche actuelle des requêtes SQL pour voir quels éléments sont dans quel état, mais à long terme, quelque chose comme ceci semble vouloir mieux fonctionner (sans avoir à apporter un changement de conception fondamental tel que le fait l’idée de la sérialisation… bien que si j’avais le temps, j’aimerais le faire de cette façon, je pense.).

Alors, est-ce ce que vous avez mentionné, ou est-ce que je m'en vais?

EDIT: Ah, je vois votre idée aussi avec l'action "Dernière action". pour déterminer l'état actuel ... j'aime ça! Je pense que cela pourrait fonctionner pour moi ... Je devrais peut-être le modifier un peu (car à un moment donné, les tâches se déroulent simultanément), mais l'idée semble être une bonne idée!

EDIT FINAL: Donc, en résumé, si quelqu'un d'autre l'exécute à l'avenir avec la même question ... il semblerait que l'approche de la sérialisation serait utile si votre système a les informations préchargées dans une interface où queryable (c.-à-d. n'appelant pas directement la base de données elle-même, comme le système ad-hoc sur lequel je travaille), mais si vous ne l'avez pas, l'idée des tables supplémentaires semble bien fonctionner! Merci à tous pour vos réponses!

Était-ce utile?

La solution

Si je comprends bien, j'ajouterais la table BoxItemTasks (juste une table d'énumération, non?), puis une table BoxItemActions avec des clés étrangères à BoxItems et à BoxItemTasks pour le type de tâche correspondant. Si vous souhaitez qu'une tâche particulière ne puisse être exécutée qu'une seule fois sur un élément de boîte particulier, il suffit que la paire de colonnes (Articles + Tâches) soit la clé primaire de BoxItemActions.

(Vous l’avez présentée beaucoup mieux que moi, et félicitations pour avoir correctement interprété ce que je disais. Ce que vous avez écrit correspond exactement à ce que j’imaginais.)

En ce qui concerne la détermination de l'état actuel, vous pouvez écrire un déclencheur sur BoxItemActions qui met à jour une colonne unique BoxItems.LastAction. Pour les actions simultanées, votre déclencheur pourrait simplement avoir des cas spéciaux pour décider quelle action doit être récente.

Autres conseils

Comme suggéré dans la réponse précédente, je diviserais votre tableau en plusieurs.

BoxItemActions, contenant une liste d'actions que le flux de travail doit exécuter, est créé chaque fois qu'un BoxItem est créé. Dans ce tableau, vous pouvez suivre les dates détaillées \ times \ users de la fin de chaque tâche.

Avec ce type d’application, il peut être très difficile de savoir où la Box doit se rendre, il est donc très utile de disposer d’une "Carte" des étapes restantes pour la Box. De plus, cette table peut grouper comme des fous, des centaines de lignes par boîte, et il sera toujours très facile d’interroger.

Il permet également d’avoir des "chemins différents" qui peuvent être facilement modifiés. Une table de données maîtresses de «chemins» dans le flux de travail constitue une solution. Chaque fois que vous créez une boîte, vous devez sélectionner le «chemin» qu’elle suivra. Ou vous pouvez configurer de sorte que lorsque l'utilisateur crée la boîte, il sélectionne des tâches requises pour cette boîte. Cela dépend de notre problème commercial.

Que diriez-vous d'un hybride de la sérialisation et des modèles de base de données. Ayez un document XML qui vous servira de document de flux de travail principal, contenant un nœud pour chaque étape avec des attributs et des éléments détaillant son nom, son ordre dans le processus, les conditions de son optionnel ou non, etc. Plus important encore, chaque nœud peut avoir un identifiant d'étape unique.

Ensuite, dans votre base de données, vous avez une structure simple à deux tables. La table BoxItems stocke vos données BoxItem de base. Ensuite, une table BoxItemActions un peu comme dans la solution que vous avez indiquée comme réponse.

Elle est essentiellement similaire à la solution acceptée comme réponse, mais au lieu d’une table BoxItemTasks pour stocker la liste principale de tâches, vous utilisez un document XML offrant davantage de flexibilité pour la définition du flux de travail.

Pour ce que cela vaut, dans BizTalk, ils "se déshydratent". modèles de message de longue durée (flux de travail et autres) en les binaires en les sérialisant dans la base de données.

Je pense que je sérialiserais l'objet de flux de travail en XML et l'enregistrerais dans la base de données avec une colonne ID. Il peut être plus difficile de faire un rapport, mais cela semble fonctionner dans votre cas.

Pour ce type de problème, considérons le schéma de base de données présenté dans http: // www. .databaseanswers.org / data_models / workflow / index.htm qui modélise une série d'événements dans un processus métier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top