Как я могу обеспечить ссылочную целостность для необязательно присутствующих уникальных ключей? - PullRequest
0 голосов
/ 29 января 2010

У нас есть несколько офисов, и в каждом офисе есть несколько отделов (в некоторых отделах есть сотрудники в нескольких отделениях). У нас есть две существующие системы, которые по-разному идентифицируют сотрудников: в одной из них сотрудники IDA идентифицируют сотрудников; в других сотрудников определены IDB.

В тех случаях, когда сотрудник идентифицируется сотрудником IDA, нам необходимо указать руководителя этого сотрудника, если таковой имеется, в SUPERVISOR_IDA.

Мой стол выглядит так:

IDA
IDB
SUPERVISOR_IDA
OFFICE
DEPARTMENT

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

Проблема в том, что IDA может иметь значение NULL (и если это так, то IDB не равен NULL) или IDB может иметь значение NULL (а если это так, то IDA не имеет значение NULL), или оба могут присутствовать.

Я пытаюсь настроить уникальные и / или первичные ключи и ограничения для обеспечения целостности базы данных.

Итак, я создал уникальный ключ (IDA, IDB, OFFICE, DEPARTMENT).

Вот моя проблема:

Мне нужно убедиться, что сотрудники ссылаются на своих руководителей. Я хотел иметь внешний ключ с собственной ссылкой, чтобы удаление супервизоров не оставляло записи о работниках-сиротах с ненулевым SUPERVISOR_IDA. Но поскольку я должен был включить IDB в свой уникальный ключ в этой таблице, если я создаю этот внешний ключ, мне необходимо включить IDB как таковой:

local PARENT_IDA -> reference IDA
local OFFICE -> reference OFFICE
local DEPARTMENT -> reference DEPARTMENT
**local IDB -> reference IDB**

Это проблема, потому что IDB сотрудника НЕ ​​должен совпадать с IDB супервизора.

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

Сначала я хотел установить уникальный ключ (IDA, OFFICE, DEPARTMENT) в дополнение к вышеупомянутому уникальному ключу, но в отличие от уникальных ключей, состоящих из одного столбца, составные уникальные ключи будут обрабатываться (null, ' A ') и (null,' A ') как дубликаты вместо разрешения пустого столбца, чтобы избежать нарушения ограничения уникальности.

Ответы [ 3 ]

2 голосов
/ 29 января 2010

Я думаю, что проблема с моделью.Таблица должна иметь первичный ключ (и если IDA или IDB могут быть нулевыми, то они не являются столбцами PK), а внешний ключ должен ссылаться на PK.

Я думаю, что вы пытаетесь использовать FK против уникальногоиндекс для принудительного применения набора правил проверки нескольких строк в модели данных, таких как «сотрудник может контролироваться только кем-то в том же офисе и отделе» и «сотрудник IDA может контролироваться только другим сотрудником IDA».

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

При этом можно попробовать добавить столбцы DEPT_IDA и OFFICE_IDA и использоватьзапускает их установку из DEPT и OFFICE, только когда установлена ​​IDA.Затем создайте Великобританию на этих столбцах

1 голос
/ 29 января 2010

Я думаю, что ваша модель данных неверна. У вас должна быть только одна запись РАБОТОДАТЕЛЯ на сотрудника. Тогда вы можете иметь unique ключи на каждой из IDA и IDB.

Поскольку сотрудники работают в нескольких офисах, вам нужна таблица для представления этого; ПОСТЫ будут таблицей пересечений между ОФИСАМИ и СОТРУДНИКАМИ.

Дело в том, что SUPERVISOR_IDA и SUPERVISOR_IDB являются свойствами POSTS, и поэтому вы можете принудительно установить внешний ключ между этими столбцами и таблицей EMPLOYEES. Используйте проверочные ограничения, чтобы гарантировать, что, если запись POSTS идентифицируется EMPLOYEE_IDA, заполнение SUPERVISOR_IDA и то же самое для EMPLOYEE_IDB.

0 голосов
/ 29 января 2010

Я не уверен, что это работает в Oracle, но в SQL Server я бы создал триггер для таблицы SUPERVISORS, который срабатывает при UPDATE и DELETE. Триггер будет запрашивать таблицу EMPLOYEES для любых записей, где SUPERVISORS.SUPERVISOR_IDA = EMPLOYEES.SUPERVISOR_IDA. Если какие-либо записи будут найдены, транзакция будет отменена.

Я нашел эту ссылку, которая описывает, что вам нужно сделать.

http://www.techonthenet.com/oracle/triggers/before_delete.php

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