Oracle: FK ссылается на PK в нескольких родительских таблицах - PullRequest
3 голосов
/ 29 марта 2011

В Oracle 10g возможно определить ограничения ссылочной целостности для внешнего ключа для ссылки на первичный ключ в нескольких родительских таблицах.

Например:

DEPT_AMER

DEPT_ID
10
11
12

DEPT_APAC

DEPT_ID
13
14
15

DEPT_EMEA

DEPT_ID
16
17
18

EMP

EMP_ID DEPT_ID
500 11
501 15

Я хочу EMP.DEPT_ID, чтобы иметь возможность ссылаться на один из идентификаторов отделов в DEPT_AMER, DEPT_APAC & DEPT_AMER.Есть ли способ определения ссылочной целостности для удовлетворения этой потребности.DEPT_ID во всех 3 таблицах генерируется из общей последовательности и гарантированно будет уникальным.

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

Ответы [ 4 ]

6 голосов
/ 28 ноября 2012

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

6 голосов
/ 29 марта 2011

У вас есть одна сущность в трех разных таблицах. Лучше всего объединить DEPT_AMER + DEPT_EMEA + DEPT_APAC в одну таблицу с именем DEPT с новым полем DEPT_TYPE (AMER или EMEA или APAC). Это лучше для поддержки функций и производительности.

Что вы будете делать, если в Антарктике откроется новый отдел? Добавить другую таблицу? Нет! Вы просто добавляете еще один тип dept_

2 голосов
/ 29 марта 2011

Вы можете определить ограничения, но они не будут делать то, что вы хотите.Вы никогда не сможете добавить что-либо в таблицу emp, потому что ключ DEPT_ID должен находиться в каждой из таблиц DEPT_.

При условии, что вы должны сохранить существующую структуру, самое простое - определитьматериализованное представление, которое объединяет каждую из этих таблиц в одно представление.ИМО, это ошибочная реализация.Я бы создал одну таблицу для информации DEPT_ со столбцом, разделяющим различные типы.

1 голос
/ 29 марта 2011

Вы не можете определить такое FK-ограничение.Но вы можете проверить целостность данных с помощью триггера.Например:

 CREATE OR REPLACE TRIGGER emp_check_dept_id_trg
    BEFORE INSERT OR UPDATE 
    on emp
    FOR EACH ROW
    DECLARE
      l_res NUMBER;
    BEGIN
      SELECT count(*) 
      INTO l_res
      FROM (
              SELECT dept_id FROM DEPT_AMER WHERE dept_id = :NEW.DEPT_ID
            UNION ALL
                SELECT dept_id FROM DEPT_APAC WHERE dept_id = :NEW.DEPT_ID
            UNION ALL
                SELECT dept_id FROM DEPT_EMEA WHERE dept_id = :NEW.DEPT_ID
          )
      ;
      IF l_res = 0 THEN
        raise_application_error(-20000, 'referential integrity violated');
      END IF;
    END;
    /
...