Внешний ключ в oracle

#sql #oracle #foreign-keys #primary-key

#sql #Oracle #внешние ключи #первичный ключ

Вопрос:

Я создал таблицу в oracle, в которой есть один FK, который ссылается на 3 первичных ключа в 3 разных таблицах.Но когда я хочу вставить в него, я вижу сообщение об ошибке, в котором говорится, что родительский ключ не найден!что мне делать?

 CREATE TABLE A
(   X       char(11)        not null,
    id      char(11)        not null,
    PRIMARY KEY(X,id),
    FOREIGN KEY(id) REFERENCES B(employee_id),
    FOREIGN KEY(id) REFERENCES C(customer_id)   
);
  

Комментарии:

1. вставили ли вы данные в свои таблицы B и C, соответствующие вашему id значению в таблице A?

2. Что-то не так с дизайном. Одно поле таблицы, ссылающееся на три разные таблицы, требующее наличия одного и того же значения в трех таблицах в качестве первичного ключа.

3. Cybernate прав. Не имеет смысла пытаться использовать один внешний ключ для значений pkey в двух разных таблицах. Я удивлен, что Oracle вообще разрешила создавать эти ограничения.

4. да, я сделал. Я сделаю так, как сказал Джастин в своем ответе, спасибо.

Ответ №1:

Если вы хотите, чтобы ID столбец в A был либо внешним ключом к EMPLOYEE_ID столбцу в B, либо внешним ключом к CUSTOMER_ID столбцу в C, у вас проблема — вы не можете объявить внешний ключ для этого отношения типа либо / или.

С точки зрения моделирования данных у вас есть несколько вариантов

  • Вы можете создать два столбца в A, EMPLOYEE_ID столбец, который является обнуляемым внешним ключом к EMPLOYEE_ID столбцу в B, и CUSTOMER_ID столбец, который является обнуляемым внешним ключом к CUSTOMER_ID столбцу в C. Затем вы можете создать ограничение проверки для A, чтобы точно один из этих двух столбцов был равен NULL.
  • Вы можете создать новую ENTITY таблицу, содержащую все EMPLOYEE_ID и CUSTOMER_ID значения. EMPLOYEE_ID в B был бы внешний ключ к ENTITY_ID столбцу в ENTITY , как и CUSTOMER_ID столбец в C и ENTITY_ID столбец в A.
  • Вы можете оставить столбцы в A отдельно и исключить внешний ключ. Тогда вы были бы ответственны за проверку ссылочной целостности в вашем коде. Этот последний вариант, как правило, не является хорошей идеей.

Как правило, я бы также с большим подозрением относился к столбцам, объявленным как CHAR (11). В Oracle практически нет случая, когда действительно имело бы смысл использовать CHAR вместо VARCHAR2. В лучшем случае, это промывка.

Комментарии:

1. лично я бы выбрал второй вариант.

2. Но если я напишу так, как вы говорите, я не могу сказать, что 2 других имеют значение null, поскольку все они являются первичными ключами. Вы понимаете, что я имею в виду?

3. Первичный ключ, составной или нет, не может содержать nulls. По определению ключи не допускают нулевых значений. Oracle не разрешает значения null в столбцах, подверженных ограничению ПЕРВИЧНОГО КЛЮЧА.

4. @Dportas — Вы абсолютно правы. Я путал семантику для составных уникальных ограничений с составными ограничениями первичного ключа. Для ясности я удалю этот комментарий. Спасибо за исправление!

Ответ №2:

Ваш столбец id в таблице A ссылается на столбец в таблице B, а также на столбец в таблице C. Если вам нужно вставить данные в таблицу A, значение в id поле должно соответствовать значению в таблицах B и C, в противном случае вы нарушаете свое ограничение FK; невозможно вставить строку в таблицу A, содержащую столбец, ссылающийся на несуществующую строку в таблице B или C.

Ответ №3:

Создайте единственную родительскую таблицу (для примера я назову ее Party). Ссылайтесь на таблицу Party из всех трех таблиц A, B, C. В результате несколько внешних ключей будут заменены одним внешним ключом, ссылающимся на таблицу Party. Это пример шаблона обобщения / специализации, «подтипа», который вы найдете во многих книгах по моделированию данных.