Этот вопрос очень конкретный в одном смысле, и некоторые люди могут утверждать, что он слишком локализован. Существует, однако, еще одна общеприменимая идея, которая может быть полезной для других людей в будущем, поэтому не обязательно верно, что вопрос слишком конкретный.
Действительно интересная часть этих бизнес-правил это одна: (мой курсив)
Один отдел может получить отнесен к более чем одной области, только если каждый область принадлежит к другому зона.
Вот схема, которая захватывает почти все из заявленных бизнес-правил декларативно, без необходимости прибегать к каким-либо триггеров.
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
. Это полезно для распространения ограничения на то, что отделы должны быть разными внутри зоны.
Assigninging департаментов регионов требует пересечения таблицы:
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 составным идентификатором и DEPT_ID, но это заставит вас решить, хотите ли вы нарушить 3NF или сделать изменения в вашем рабочем отделе процедурно уродливым. В конце концов, небольшой триггер, чтобы убедиться, что EMP_ASGT не противоречит EMPLOYEE.DEPT_ID, будет гораздо меньше проблем.
Можете ли вы предоставить более подробную информацию о том, какие сущности являются родителями, а какие являются детьми? Похоже, что L может быть родителем S или, может быть, нет? Как может быть, что у S1 есть два разных родителя? Какова мощность отношений между R и S в каждом направлении и каково значение разницы между R1-S1 и R2-S1? –
@JoelBrown Объяснил ситуацию другим словом. Надеюсь это поможет. – SteAp