Рекомендации: Хранить состояние рабочего процесса элемента в базе данных? - PullRequest
12 голосов
/ 22 сентября 2008

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

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

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

Есть TaskName Complete

Дата TaskName Complete

Пользователь TaskName Complete

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

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

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

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

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

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

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

EDIT:

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

BoxItems

(PK) BoxItemID

(Другие не относящиеся к делу вещи)

BoxItemActions

(PK) BoxItemID

(PK) BoxItemTaskID

IsCompleted

DateCompleted

UserCompleted

BoxItemTasks

(PK) TaskType

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

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

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

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

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

Ответы [ 6 ]

4 голосов
/ 22 сентября 2008

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

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

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

3 голосов
/ 22 сентября 2008

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

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

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

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

1 голос
/ 10 октября 2011

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

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

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

0 голосов
/ 23 сентября 2008

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

0 голосов
/ 22 сентября 2008

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

0 голосов
/ 22 сентября 2008

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

...