Лучшие практики:Сохранение состояния рабочего процесса элемента в базе данных?

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

Вопрос

У меня вопрос о лучших практиках относительно того, как следует подходить к хранению сложных состояний рабочего процесса для обработки задач в базе данных.Я безуспешно искал в Интернете, поэтому решил спросить сообщество, что, по их мнению, лучше всего.

Этот вопрос возникает из того же примера «BoxItem», который я привел в предыдущем вопросе.Этот «BoxItem» отслеживается в моей системе по мере выполнения над ним различных задач.Задача может выполняться в течение нескольких дней и при участии человека, поэтому состояние BoxItem должно сохраняться.Также необходимо отслеживать, кто выполнил задание (если применимо) и когда задание было выполнено.

Сначала я подошел к этому, добавив три поля в таблицу «BoxItems» для каждой интерактивной задачи, которую необходимо было выполнить:

ЯвляетсяИмя задачиПолный

ДатаИмя задачиПолный

ПользовательИмя задачиПолный

Это работало, когда рабочий процесс был простым...но теперь, когда это превратилось в сложный процесс (> 10 возможных человеческих взаимодействий в потоке...около половины из них являются необязательными и могут быть или не быть выполнены для BoxItem, в результате чего я начал добавлять «DoИмя задачи", а также для этих необязательных задач), я обнаружил, что то, что должно было быть простой таблицей, теперь имеет около 40 полей, полностью посвященных сохранению этой информации о состоянии.

Я спрашиваю, нет ли лучшего способа сделать это...но я в растерянности.

Моей первой мыслью было создать общую таблицу «BoxItemTasks», в которой определялись бы задачи, которые можно выполнять в данном блоке, но мне все равно нужно было бы сохранять информацию о дате и пользователе по отдельности, так что это не особо помогло.

Моя вторая мысль заключалась в том, что, возможно, это не имеет значения, и мне не следует беспокоиться, если в этой таблице есть 40 или более полей, предназначенных для сохранения состояния...а может у меня просто паранойя.Но такое ощущение, что нужно сохранить много информации.

В любом случае, я не понимаю, каким может быть третий вариант, и является ли один из двух вышеперечисленных вариантов действительно разумным.Я вижу, что в будущем этот рабочий процесс может стать еще более сложным, и для каждой новой задачи мне придется добавлять 3-4 поля только для поддержки ее отслеживания...такое ощущение, что ситуация выходит из-под контроля.

Что бы вы сделали в такой ситуации?

Я должен отметить, что это обслуживание существующей системы, которая была построена без ORM, поэтому я не могу просто предоставить ORM позаботиться об этом.

РЕДАКТИРОВАТЬ:

Кев, ты говоришь о том, чтобы сделать что-то вроде этого:

BoxItems

(ПК) BoxItemID

(Другие ненужные вещи)

Действия BoxItem

(ПК) BoxItemID

(ПК) BoxItemTaskID

Выполнен

Дата завершения

Пользователь завершен

BoxItemЗадачи

(ПК) Тип задачи

Описание (если даже необходимо)

Хм...это сработает...это означало бы необходимость изменить мой текущий подход к выполнению SQL-запросов, чтобы увидеть, какие элементы находятся в каком состоянии, но в долгосрочной перспективе что-то вроде этого будет работать лучше (без необходимости вносить фундаментальные изменения в дизайн, такие как идея сериализации). представляет собой...хотя, если бы у меня было время, я бы с удовольствием сделал именно так.).

Так это то, о чем ты говорил, Кин, или я сбился с пути?

РЕДАКТИРОВАТЬ:Ах, я тоже вижу вашу идею с «Последним действием» для определения текущего состояния...Мне это нравится!Я думаю, что это может сработать для меня...Возможно, мне придется немного изменить это (потому что в какой-то момент задачи выполняются одновременно), но идея кажется хорошей!

РЕДАКТИРОВАТЬ ОКОНЧАТЕЛЬНЫЙ:Подводя итог, если кто-то еще будет искать это в будущем с тем же вопросом...похоже, что подход сериализации был бы полезен, если в вашей системе информация предварительно загружена в какой-то интерфейс, где она доступна для запроса (т.е.не вызывая напрямую саму базу данных, как это делает специальная система, над которой я работаю), но если у вас этого нет, идея дополнительных таблиц, похоже, должна работать хорошо!Спасибо всем за ваши ответы!

Это было полезно?

Решение

Если я правильно понимаю, я бы добавил таблицу BoxItemTasks (просто таблицу перечисления, да?), затем таблицу BoxItemActions с внешними ключами в BoxItems и в BoxItemTasks для того, какой это тип задачи.Если вы хотите сделать так, чтобы конкретную задачу можно было выполнить только один раз для определенного элемента ящика, просто сделайте пару столбцов (Items + Tasks) первичным ключом BoxItemActions.

(Вы изложили это гораздо лучше, чем я, и спасибо за правильную интерпретацию того, что я говорю.Вы написали именно то, что я себе представлял.)

Что касается определения текущего состояния, вы можете написать триггер в BoxItemActions, который обновляет один столбец BoxItems.LastAction.Для одновременных действий ваш триггер может иметь особые случаи, чтобы решить, какое действие требует недавности.

Другие советы

Как предлагалось в предыдущем ответе, я бы разбил вашу таблицу на несколько.

BoxItemActions, содержащий список действий, которые должен выполнить рабочий процесс, создается каждый раз при создании BoxItem.В этой таблице вы можете отслеживать подробные даты\время\пользователи выполнения каждой задачи.

В этом типе приложения узнать, куда Box будет двигаться дальше, может быть довольно сложно, поэтому наличие «Карты» оставшихся шагов для Box окажется весьма полезным.Кроме того, эта таблица может группироваться как сумасшедшая, по сотням строк в каждом блоке, и к ней все равно будет очень легко выполнять запросы.

Это также позволяет иметь «разные пути», которые можно легко изменить.Таблица основных данных «путей» в рабочем процессе является одним из решений, где при создании каждого блока пользователь должен выбрать, по какому «путю» будет следовать блок.Или вы можете настроить так, чтобы, когда пользователь создает ящик, он выбирал задачи, необходимые для этого конкретного ящика.Зависит от нашей бизнес-задачи.

Как насчет гибрида сериализации и моделей баз данных?Создайте XML-документ, который будет служить вашим основным документом рабочего процесса, содержащим узел для каждого шага с атрибутами и элементами, в которых подробно описывается его имя, порядок в процессе, условия того, является ли он необязательным или нет, и т. д.Самое главное, что каждый узел шага может иметь уникальный идентификатор шага.

Тогда в вашей базе данных будет простая структура из двух таблиц.Таблица BoxItems хранит ваши основные данные BoxItem.Затем таблица BoxItemActions, очень похожая на решение, которое вы отметили как ответ.

По сути, это решение похоже на решение, принятое в качестве ответа, но вместо таблицы BoxItemTasks для хранения основного списка задач вы используете XML-документ, который обеспечивает некоторую большую гибкость для фактического определения рабочего процесса.

Что бы это ни стоило, в BizTalk они «обезвоживают» долго исполняющиеся шаблоны сообщений (рабочие процессы и т.п.) путем двоичной сериализации их в базу данных.

Я думаю, что я бы сериализовал объект рабочего процесса в XML и сохранил его в базе данных со столбцом идентификатора.Об этом может быть сложнее сообщить, но похоже, что в вашем случае это может сработать.

Для решения такого рода проблем рассмотрим схему базы данных, показанную на рис. http://www.databaseanswers.org/data_models/workflow/index.htm который моделирует серию событий бизнес-процесса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top