Pregunta

Tengo una pregunta sobre las mejores prácticas con respecto a cómo se debe abordar el almacenamiento de estados de flujo de trabajo complejos para procesar tareas en una base de datos.He estado buscando en línea sin éxito, así que pensé en preguntarle a la comunidad qué pensaban que era mejor.

Esta pregunta surge del mismo ejemplo de "BoxItem" que di en una pregunta anterior.Este "BoxItem" está siendo rastreado en mi sistema a medida que se realizan varias tareas en él.La tarea puede llevarse a cabo durante varios días y con interacción humana, por lo que el estado del BoxItem debe persistir.También se debe realizar un seguimiento de quién realizó la tarea (si corresponde) y cuándo se realizó.

Al principio, abordé esto agregando tres campos a la tabla "BoxItems" para cada tarea interactiva humana que debía realizarse:

EsNombre de la tareaCompleto

FechaNombre de la tareaCompleto

UsuarioNombre de la tareaCompleto

Esto funcionó cuando el flujo de trabajo era simple...pero ahora que se ha convertido en un proceso complejo (> 10 posibles interacciones humanas en el flujo...aproximadamente la mitad de los cuales son opcionales y pueden o no hacerse para BoxItem, lo que me llevó a comenzar a agregar "HacerNombre de la tarea"campos también para esas tareas opcionales), descubrí que lo que debería haber sido una tabla simple ahora tiene aproximadamente 40 campos dedicados por completo a retener esta información de estado.

Me pregunto si no hay una mejor manera de hacerlo...pero estoy perdido.

Lo primero que pensé fue crear una tabla genérica "BoxItemTasks" que definiera las tareas que se pueden realizar en un cuadro determinado, pero aún así necesitaría guardar la información de Fecha y Usuario individualmente, por lo que realmente no ayudó.

Mi segundo pensamiento fue que tal vez no importaba, y no debería preocuparme si esta tabla tiene 40 o más campos dedicados a la retención del estado...y tal vez solo estoy siendo paranoico.Pero parece que hay mucha información que retener.

De todos modos, no sé cuál podría ser una tercera opción, o si una de las dos opciones anteriores es realmente razonable.Puedo ver que este flujo de trabajo potencialmente se volverá aún más complejo en el futuro, y para cada nueva tarea necesitaré agregar 3 o 4 campos solo para respaldar su seguimiento...se siente como si estuviera fuera de control.

¿Qué haría usted en esta situación?

Debo señalar que esto es el mantenimiento de un sistema existente, uno que fue construido sin un ORM, por lo que no puedo dejar que el ORM se encargue de ello.

EDITAR:

Kev, ¿estás hablando de hacer algo como esto?

Artículos de caja

(PK) ID de artículo de caja

(Otras cosas irrelevantes)

BoxItemAcciones

(PK) ID de artículo de caja

(PK) BoxItemTaskID

Esta completado

Fecha de finalización

Usuario completado

Tareas de elemento de caja

(PK) Tipo de tarea

Descripción (si es necesario)

Mmm...eso funcionaria...representaría la necesidad de cambiar la forma en que actualmente abordo las consultas SQL para ver qué elementos están en qué estado, pero a largo plazo algo como esto parece que funcionaría mejor (sin tener que hacer un cambio de diseño fundamental como la idea de serialización). representa...aunque si tuviera tiempo, creo que me gustaría hacerlo de esa manera).

Entonces, ¿es esto lo que mencionabas, Kin, o estoy equivocado?

EDITAR:Ah, también veo tu idea con la "Última acción" para determinar el estado actual...¡Me gusta!Creo que eso podría funcionar para mí...Puede que tenga que cambiarlo un poco (porque en algún momento las tareas suceden al mismo tiempo), ¡pero la idea parece buena!

EDITAR FINAL:Entonces, en resumen, si alguien más busca esto en el futuro con la misma pregunta...Parece que el enfoque de serialización sería útil si su sistema tiene la información precargada en alguna interfaz donde se pueda consultar (es decir,no llamar directamente a la base de datos, como lo hace el sistema ad-hoc en el que estoy trabajando), pero si no tienes eso, ¡la idea de las tablas adicionales parece que debería funcionar bien!¡Gracias a todos por sus respuestas!

¿Fue útil?

Solución

Si entiendo correctamente, agregaría la tabla BoxItemTasks (solo una tabla de enumeración, ¿verdad?), luego una tabla BoxItemActions con claves externas para BoxItems y BoxItemTasks para el tipo de tarea que es.Si desea que una tarea en particular solo se pueda realizar una vez en un elemento de cuadro en particular, simplemente haga que el par de columnas (Elementos + Tareas) sea la clave principal de BoxItemActions.

(Lo expusiste mucho mejor que yo y te felicito por interpretar correctamente lo que estaba diciendo.Lo que escribiste es exactamente lo que me estaba imaginando).

En cuanto a determinar el estado actual, puede escribir un activador en BoxItemActions que actualice una sola columna BoxItems.LastAction.Para acciones concurrentes, su desencadenante podría tener casos especiales para decidir qué acción es reciente.

Otros consejos

Como sugirió la respuesta anterior, dividiría su tabla en varias.

BoxItemActions, que contiene una lista de acciones por las que debe pasar el flujo de trabajo, creada cada vez que se crea un BoxItem.En esta tabla, puede realizar un seguimiento de las fechas, horas y usuarios detallados en los que se completó cada tarea.

Con este tipo de aplicación, saber dónde debe ir el Box a continuación puede resultar bastante complicado, por lo que tener un 'Mapa' de los pasos restantes del Box resultará muy útil.Además, esta tabla puede agrupar como locas cientos de filas por cuadro, y aún así será muy fácil de consultar.

También hace posible tener "diferentes caminos" que pueden cambiarse fácilmente.Una tabla de datos maestros de 'rutas' a través del flujo de trabajo es una solución, donde a medida que se crea cada cuadro, el usuario tiene que seleccionar qué 'ruta' seguirá el cuadro.O puede configurarlo para que cuando el usuario cree el cuadro, seleccione las tareas necesarias para este cuadro en particular.Depende de nuestro problema empresarial.

¿Qué tal un híbrido de los modelos de serialización y de base de datos?Tenga un documento XML que sirva como documento maestro de flujo de trabajo, que contenga un nodo para cada paso con atributos y elementos que detallen su nombre, orden en el proceso, condiciones para determinar si es opcional o no, etc.Lo más importante es que cada nodo de paso puede tener una identificación de paso única.

Luego, en su base de datos tiene una estructura simple de dos tablas.La tabla BoxItems almacena sus datos básicos de BoxItem.Luego, una tabla BoxItemActions muy parecida a la de la solución que marcó como respuesta.

Es esencialmente similar a la solución aceptada como respuesta, pero en lugar de una tabla BoxItemTasks para almacenar la lista maestra de tareas, se utiliza un documento XML que permite más flexibilidad para la definición del flujo de trabajo real.

Por si sirve de algo, en BizTalk "deshidratan" patrones de mensajes de larga duración (flujos de trabajo y similares) serializándolos binariamente en la base de datos.

Creo que serializaría el objeto de flujo de trabajo en XML y lo almacenaría en la base de datos con una columna de ID.Puede que sea más difícil informar sobre ello, pero parece que puede funcionar en su caso.

Para este tipo de problema, considere el esquema de base de datos que se muestra en http://www.databaseanswers.org/data_models/workflow/index.htm que modela una serie de eventos en un proceso empresarial.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top