дизайн базы данных один ко многим ко многим - PullRequest
0 голосов
/ 04 ноября 2011

Я работаю над дизайном базы данных для приложения рабочего процесса веб-приложения Java для отслеживания и проверки различных бизнес-продуктов (документов). Но у меня есть ряд неопределенностей с его дизайном и реализацией.
Вот мои таблицы:

  • WORK_FLOW_CLASS - таблица определений рабочих потоков по видам продукции, т. Е. Отчеты, презентации, инженерные расчеты

  • ROLE_CLASS - таблица определения ролей рабочего потока, т. Е. Инициатор, контролер, утверждающий, менеджер

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

  • WORK_ACTION_CLASS - определение действий рабочего элемента, а именно: полный контрольный список расчетов (a WORK_ITEM) по Checker (a ROLE), полный отчет по проверке (a WORK_ITEM) по Manager (a ROLE), полный отчет по рассмотрению (a WORK_ITEM) по утверждению (a ROLE)

  • WORK_FLOW_SEQUENCE - таблица определения, связывающая WORK_FLOW_CLASS с MANY WORK_ITEM_CLASS es, т. Е. ABC уровня 1 Последовательность расчетов: (1) Форма назначения, (2) Контрольный список расчета, (3) Закрытие Контрольный список. Последовательность расчетов для уровня 1 отдела XYZ: (1) Форма назначения, (2) Контрольный список проверки [XYZ решил не выполнять контрольный список в своем рабочем процессе Calc].

Первый вопрос: Должен ли WORK_ACTION_CLASS иметь FK, чтобы связать его с WORK_ITEM_CLASS?

Или я должен использовать промежуточную таблицу, чтобы обеспечить связь? Я думаю, что последнее было бы ненужным, потому что мне не нужно связывать WORK_ACTION с несколькими WORK_ITEMS, только с одним.

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

  • WORK_FLOW_INSTANCE - Фактический экземпляр рабочего процесса - я думаю, как заказ в корзине

  • WFI_WORK_ITEMS - Позиции экземпляра рабочего потока WORK_ITEMs - я думаю, как продукты в Заказе

  • WFI_WORK_ITEM_ACTIONS - Действия с рабочим элементом экземпляра рабочего потока

Здесь мне нужна помощь по второму вопросу .

Должны ли быть две отдельные таблицы WFI_WORK_ITEMS и WFI_WORK_ITEM_ACTIONS или у меня должна быть одна составная таблица? Мне нужно будет запросить только WORK_ITEMS в экземпляре рабочего потока, а также WORK_ITEMS с подэтапом WORK_ACTIONS.

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

WFI_WORK_ITEMS
==============
WFI_WORK_ITEM_ID (PK) 
WORKFLOW_INSTANCE_ID (FK) 
WORK_ITEM_CLASS_ID (FK)
STEP_NUM
LAST_DATE
STATUS
IS_ACTIVE


WFI_WORK_ITEM_ACTION
====================
WFI_WORK_ITEM_ACTION_ID (PK) 
WORKFLOW_INSTANCE_ID (FK)
WFI_WORK_ITEM_ID (FK) 
WORK_ITEM_CLASS_ID (FK)
STEP_NUM
WORK_ACTION_CLASS_ID (FK)
ACTION_OWNER
LAST_DATE DATE
STATUS
IS_ACTIVE

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

Любая помощь с моим дизайном приветствуется.

EDIT Под избыточными данными я понимал, что в обеих таблицах перечислены WORKFLOW_INSTANCE_ID и WORK_ITEM_CLASS_ID. Я подумал, что если бы я хотел узнать WORK_ITEM_ACTIONS для конкретного экземпляра WORKFLOW, я мог бы получить его, запросив таблицу WFI_WORK_ITEM_ACTION без присоединения таблица «WFI_WORK_ITEM». Может быть, это неправильное мышление. То же самое для WORK_ITEM_CLASS_ID. Запрашивая таблицу WFI_WORK_ITEM_ACTION, я узнал бы тип WORK_ITEM, для которого было выполнено действие.

Это лучший дизайн?

WFI_WORK_ITEM
==============
WFI_WORK_ITEM_ID (PK) 
WORKFLOW_INSTANCE_ID (FK) 
WORK_ITEM_CLASS_ID (FK)
<b>WORK_ITEM_</b>STEP_NUM
<b>WORK_ITEM_</b>LAST_DATE
<b>WORK_ITEM_</b>STATUS
<b>WORK_ITEM_</b>IS_ACTIVE


WFI_WORK_ITEM_ACTION
====================
WFI_WORK_ITEM_ACTION_ID (PK) 
<strike>WORKFLOW_INSTANCE_ID (FK)</strike>
WFI_WORK_ITEM_ID (FK) 
<strike>WORK_ITEM_CLASS_ID (FK)</strike>
<b>WORK_ACTION_</b>STEP_NUM
WORK_ACTION_CLASS_ID (FK)
ACTION_OWNER
<b>WORK_ACTION_</b>LAST_DATE
<b>WORK_ACTION_</b>STATUS
<b>WORK_ACTION_</b>IS_ACTIVE

1 Ответ

4 голосов
/ 04 ноября 2011

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

(немного упрощенное) правило, которое нужно помнить, состоит в том, что каждыйнеключевой столбец в таблице должен зависеть от:

  • ключа,
  • всего ключа
  • и только от ключа
  • «Помоги мне, Кодд» - немного юмора DBA (и я имею в виду «мало»).

Первый вопрос довольно прост.

Один ко многимотношения лучше всего представлены как внешний ключ в таблице «многие».Поэтому то, что вы предлагаете, имеет смысл.Это позволяет автоматически ограничивать отношения.Если бы у вас была отдельная таблица присоединения (использовалась для многих ко многим), вам пришлось бы прибегнуть к «хитрости», чтобы навязать отношение «один ко многим».

Что касается вашего второго вопроса, вам нужновзгляните на правило «Кодд» выше и подумайте: что именно представляют эти строки в каждой таблице?Если действие рабочего элемента является отдельным объектом от рабочего элемента (они могут быть связаны , но, если они не представляют один и тот же объект, они различаются), они должны быть в разных таблицах.

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

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

Используя step_num в качестве примера, что именно это представляет?Если это атрибут рабочего элемента , то его вообще не должно быть в таблице action .

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

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

Конечно, у вас может быть отдельный номер шага для обоихдействия и - в этом случае, я бы рассмотрел переименование, чтобы прояснить намерение, что-то вроде item_step_num и action_step_num.

. Нижняя строка должна начинаться с 3NF.Если в какой-то момент ваша база данных работает слишком медленно, , тогда рассмотрите возможность возврата в меньшую форму.Затем вы можете задать еще один вопрос здесь о том, как распознать и смягчить проблемы, которые возникают из-за этого (например, возможность несогласованности данных в двух местах и ​​использование триггеров для предотвращения этого).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...