Дизайн базы данных для обновляемых последовательных записей

dba.stackexchange https://dba.stackexchange.com/questions/18954

  •  22-10-2019
  •  | 
  •  

Вопрос

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

Я пытаюсь моделировать процессы и включать родительские процессы и последовательный порядок процессов.

Например:

Process Table
---------------------
ProcessID - uniqueidentifier
ProcessName - varchar
ProcessDescription - varchar
...

ProcessOrder Table
---------------------
ProcessID - uniqueidentifier FK - Process
ParentProcessID - uniqueidentifier FK - Process
ProcessOrder - int
...

А ProcessOrder колонка в ProcessOrder Таблица будет просто хранить число, представляющее, какой последовательный шаг в родительском процессе он представляет.

Например, процедура моделирования имеет следующие шаги: Создайте новую пустую модель, модель имени, введите параметры модели. А Process Таблица будет выглядеть как:

ProcessID | ProcessName | ProcessDescription
-------------------------------------------------
UUID1     | Modeling    | Create Model of Data
UUID2     | New Model   | create new empty model
UUID3     | Name Model  | name model
UUID4     | Parameters  | enter model parameters

А ProcessOrder Таблица будет выглядеть как:

ProcessID | ParentProcessID | ProcessOrder
--------------------------------------------------
UUID2     | UUID1           | 1
UUID3     | UUID1           | 2
UUID4     | UUID1           | 3

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

Есть ли лучший способ хранить такие данные и поддерживать нормализацию?

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

Решение

Ваш дизайн кажется мне разумным. Хотя вам нужно обновить все последующие записи, когда добавляются или удаляются новые процессы, которые легко выполнить. Вы просто выпускаете обновление, например:

UPDATE ProcessOrder
SET ProcessOrder = ProcessOrder+1
WHERE ProcessOrder >= [step# where you want to insert]

а затем сделайте свою вставку или удалите.

Единственный другой способ, о котором я могу придумать, - это разработка схемы для хранения следующего идентификатора процесса в ряду. Что-то типа:

ProcessID | ParentProcessID | NextId
--------------------------------------------------
UUID2     | UUID1           | UUID3
UUID3     | UUID1           | UUID4
UUID4     | UUID1           | NULL

Затем, если вы вставите новый шаг - скажем, между UUID3 и UUID4, вы выполняете больше связанной операции списка, которая будет обновлять UUID3 | UUID1 NextID для UUID5, а затем просто вставьте новый UUID5 с помощью следующего UUID4.

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

Вам нужно решить, какой процесс вы хотите отдать предпочтение - вставить и обновлять или извлекать. Если вы предпочитаете поиск (что вы могли бы, если изменения нечастые, а отчетность часто бывает, а списки короткие), то перейдите с исходным дизайном. Если вы предпочитаете вставку и обновление (что вы могли бы, если изменения происходят все время, а отчетность нечасто, или списки действительно действительно длинные), то перейдите с подходом Linked List.

Надеюсь, это поможет. Заинтересованы в том, какие другие решения могут придумать сообщество, так как я хотел бы расширить свои знания по этому поводу!

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

Если все, что вам нужно, это сохранить, какой шаг вашего процесса идет после того, как предыдущий шаг, то все, что вам нужно, это следующее:

ProcessId | ParentProcessId | Предыдущий Processid

Конечно, вам понадобится ограничение FK, чтобы убедиться, что (ParentProcessId | предыдущий процесс) указывает на действительный (ParentProcessId | ProcessId)

Если я понял ваши требования, и этот дизайн действителен, то легко вставить/удалить/перемещать шаги в вашем процессе - вам не нужно распространять какие -либо изменения в ваших дочерних таблицах, потому что они относятся к вашему основному ключу (ParentProcessId | ProcessID).

HIH

Пара вопросов сначала ...

  1. Почему вы собираетесь использовать уникальные идентификаторы в качестве ключевых столбцов? Я вижу это часто делается в базах данных, и я никогда не уверен, почему. Если вам действительно нужна запись, чтобы быть уникальной на протяжении всей базы данных или даже в нескольких системах/базах данных, это прекрасно. Однако, если это не так, и вам просто нужно, чтобы запись была уникальной в таблице, то используйте целочисленное значение. Даже если вам нужно использовать Bigint, вам будет лучше; Тип Bigint составляет 8 байтов, тогда как уникальный идентификатор хранится как 16 -байтовая двоичная строка.
  2. Как выглядит рабочий процесс на уровне приложения в отношении обновления заказа процесса? Причина, по которой я спрашиваю, заключается в том, что вы можете избежать нескольких операторов обновления, если вы можете сохранить все в локальной памяти, пока рабочий процесс не будет завершен. Например, если приложение Front End представляет собой веб -приложение ASP.NET, вы можете сохранить все в состоянии сеанса, позволить пользователям завершить весь рабочий процесс, а затем выполнить одну операцию базы данных.
  3. Возможно ли, что несколько пользователей будут работать с компонентами одного и того же рабочего процесса одновременно? Если это так, вам нужно будет установить чеки, которые гарантируют, что два пользователя не могут наступить на ноги друг друга.
  4. Как насчет истории процесса для аудита и отчетности? Если вы обновите записи, вы полностью потеряете всю историю. Вы никогда не сможете представить отчет, который показывает различные шаги процесса, время, необходимое для перехода от одного к другому и т. Д.

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

Шаг процесса не имеет значения в вашем случае, если не определена версия процесса. Таким образом, вы могли бы сказать, что процесс 1 имеет свои шаги, выполненные в этом порядке (A, B, D, C), когда процесс был в версии 1, но в версии 2 порядок выполнения шага изменился на (A, B, C). Поэтому я думаю, что версия процесса важна.

Диаграмма ниже представляет мое предложение.

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

enter image description here

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