Моделирование иерархической структуры данных - PullRequest
1 голос
/ 02 марта 2012

20120304 - Упорядоченный вопрос

Предположим, у нас есть сущности R, D и E, и это количество элементов связи

  • R D
  • D <1: n> E

Отображение этой спецификации является прямым, но у нас есть другое требование:

  • R E

Условие стороны: E1 может быть «назначен» только для R1, если E1 относится к некоторому D1, а этот D1 относится к R1.

К сожалению, даже если E2 относится к D2, который относится к R2 - E2 может не относиться к R2.

  • Я ищу модель реляционной БД.
  • Модель, для которой не требуется многократное обновление , если D отсоединяется от Ra и присоединяется к другому Rb. В этом случае все Es of D нужно отделить от Ra и привязать к Rb.

20120305 - Обходной путь?

Друг предлагает создать объект DxR, который связывает его D и R посредством кортежа (D, R). Затем создайте отношение

  • DxR E

Хм ...

20120302 - Оригинальный вопрос

Система состоит из зон верхнего уровня (Z) . Зона может иметь несколько областей (R) .

Так называемые отделы (D) могут быть назначены регионам . Один департамент может быть назначен более чем одному региону, только если каждый регион принадлежит другой зоне.

Наконец, сотрудников (E) принадлежат одному и только одному отделу .

Сотрудники могут быть назначены в регион, только если отдел сотрудника принадлежит области.

Важно: Сотрудник не обязательно должен принадлежать всем регионам, к которым относится его отдел.

Предположим, что на следующем графике E1 принадлежит D1. E1 также должен принадлежать R1, но не принадлежать R2 - хотя D1 принадлежит R1 и R2:

-     Z            Z
-   __|___      ___|___
-   R1   R      R2    R
-    \_________/
-     D1         

В: Пожалуйста, предложите структуру таблицы БД отношений, которая моделирует вышеуказанную спецификацию?

1 Ответ

1 голос
/ 04 марта 2012

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

Действительно интересная часть этих бизнес-правил: (мой акцент добавлен)

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

Вот схема, которая почти декларирует все заявленные бизнес-правила декларативно, не прибегая к каким-либо триггерам.

create table ZONE
( ID int not null
, NAME varchar(50) not null
, constraint PK_ZONE primary key clustered (ID)
)

create table REGION
( ZONE_ID int not null
, REGION_ID int not null
, NAME varchar(50) not null
, constraint PK_REGION primary key clustered (ZONE_ID, REGION_ID)
, conttraint FK_REGION__ZONE foreign key (ZONE_ID) 
    references ZONE (ID)
)

create table DEPARTMENT
( ID int not null
, NAME varchar(50) not null
, constraint PK_DEPARTMENT primary key clustered (ID)
)

create table EMPLOYEE
( ID int not null
, NAME varchar(50) not null
, DEPT_ID int not null
, constraint PK_EMPLOYEE primary key clustered (ID)
, constraint FK_EMPLOYEE__DEPARTMENT foreign key (DEPT_ID) 
    references DEPARTMENT (ID)
)

Приведенные выше таблицы довольно очевидны. Однако есть одна особенность: у таблицы REGION есть составной первичный ключ, который включает FK в ZONE. Это полезно для распространения ограничения на то, что отделы должны различаться в пределах зоны.

Для присвоения отделов регионам требуется таблица пересечений:

create table DEPT_ASGT -- Department Assignment
( REGION_ID int not null
, DEPT_ID int not null
, ZONE_ID int not null
, constraint PK_DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_DEPT_ASGT__REGION foreign key (ZONE_ID, REGION_ID) 
    references REGION (ZONE_ID, ID)
, constraint FK_DEPT_ASGT__DEPARTMENT foreign key (DEPT_ID) 
    references DEPARTMENT (ID)
, constraint UN_DEPT_ASGT__ZONES unique nonclustered (ZONE_ID, DEPT_ID)
)

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

Наконец, нам нужно сопоставить сотрудников с отделами и регионами. Для этого требуется другая таблица пересечений:

create table EMP_ASGT -- Employee Assignment
( REGION_ID int not null
, DEPT_ID int not null
, EMPLOYEE_ID int not null
, constraint PK_EMP_ASGT (REGION_ID, DEPT_ID, EMPLOYEE_ID)
, constraint FK_EMP_ASGT__DEPT_ASGT (REGION_ID, DEPT_ID) 
    references DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_EMP_ASGT__EMPLOYEE (EMPLOYEE_ID) refernces EMPLOYEE (ID)
)

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

Это единственное место, где необходим триггер или какая-то другая процедурная логика. Вы должны убедиться, что EMPLOYEE.department_id остается согласованным с записями в EMP_ASGT. Вы можете попытаться внедрить это в декларативную ссылочную целостность, сделав PK EMPLOYEE соединением ID и DEPT_ID, но это заставит вас решить, хотите ли вы нарушить 3NF или сделать так, чтобы ваш отдел персонала изменил процедурно-уродливый беспорядок. В конце концов, небольшой триггер, чтобы убедиться, что EMP_ASGT не расходится с EMPLOYEE.DEPT_ID, будет намного меньше проблем.

...