SQL с внешним ключом: как я могу ссылаться на два атрибута в одной таблице на составной первичный ключ, который содержит 3 столбца в другой таблице?

#sql #foreign-keys #primary-key #ddl

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

Вопрос:

 CREATE TABLE SECTION,`
SectionNo int,
Semester CHAR(7),
CourseID CHAR(8),
PRIMARY KEY (SectionNo, Semester, CourseID),
FOREIGN KEY (CourseID) REFERENCES COURSE (CourseID),

);

CREATE TABLE REGISTRATION(
StudentID int,
SectionNo int,
Semester char(7),
PRIMARY KEY (StudentID, SectionNo, Semester),
FOREIGN KEY (SectionNo, Semester) REFERENCES Section (SectionNo, Semester), 
  

В разделе «Раздел» появляется подчеркивание. Ошибка гласит: «В разделе таблицы, на которую ссылается ссылка, нет первичных или потенциальных ключей, которые соответствуют списку столбцов ссылки во внешнем ключе». Как мне это исправить ?!

 FOREIGN KEY (StudentID) REFERENCES Student (StudentID),

);
  

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

1. Что ж, сообщение об ошибке правильное. Вы не можете однозначно идентифицировать строку, Section используя только SectionNo и Semester , учитывая, что объявленный первичный ключ также включает CourseID . Мы могли бы помочь больше, если бы вы предложили нам какое-либо фактическое объяснение того, что вы пытаетесь смоделировать.

2. Мне были предоставлены сущности, атрибуты и типы данных для создания шести разных таблиц. Таблица РАЗДЕЛОВ имеет 3 первичных ключа, поэтому я не могу добавить только SectionNo и Semester в одну скобку в таблице РАЗДЕЛОВ. Есть предложения?

3. Если под «регистрацией» вы подразумеваете » Section таблицу», то нет, у нее нет 3 первичных ключей (действительно, в SQL вы ограничены максимум одним PK на таблицу, отсюда и слово primary в его названии). Он имеет один первичный ключ, который содержит 3 столбца. Это означает, что для ссылки на этот первичный ключ вам нужны 3 столбца, содержащие те же типы данных, что и в оригинале.

4. Представьте, что ваша Section таблица содержит две строки (столбцы в том же порядке, как показано в вашем вопросе): — строка 1 содержит 1,abc,def и строка 2 содержит 1,abc,ghi . То есть они предназначены для двух разных курсов, но имеют одинаковые SectionNo Semester значения и . Теперь мы вставляем строку в Registration : 2,1,abc — что означает эта регистрация?

5. Спасибо за объяснение. Итак, как мне ссылаться на SectionNo и Semester в таблице РЕГИСТРАЦИИ, поскольку в первичном ключе три столбца?

Ответ №1:

Вероятно

Судя (uh… угадайте) из выбранных вами имен студент должен зарегистрироваться в определенном семестре в определенном разделе определенного курса. Таким образом, в вашей регистрационной таблице, вероятно, отсутствует столбец курса.

Для 3-столбцового PK будет 3-столбцовый FK. Также регистрационным PK будут все 4 столбца.

Но если

Если бы вы записывали только семестр и курс, это была бы зависимость включения (IND) от РЕГИСТРАЦИИ до КУРСА. Внешний ключ (FK) является IND для ключа. (Ну, в SQL это IND для суперключей, SQL KEY / UNIQUE.) IND из столбцов в другие означает, что каждое исходное значение подстроки ahs отображается как целевое значение подстроки. Т.Е. проекция источника на его столбцы IND МИНУС проекция цели на его столбцы IND должна быть пустой.

Это IND означает, что каждое значение подстроки семестрового курса РЕГИСТРАЦИИ должно отображаться как значение подстроки КУРСА. Что означает

 NOT EXISTS (
        SELECT Semester,Course FROM REGISTRATION
    EXCEPT SELECT Semester,Course FROM COURSE
)
  

Если у вас нет EXCEPT / MINUS, тогда есть идиома с ЛЕВЫМ СОЕДИНЕНИЕМ.

Вы хотите

Вы не можете легко выразить это ограничение в большинстве СУБД SQL. (Хотя стандарт описывает функциональность.) Обычно вам приходится использовать триггеры при обновлениях, чтобы проверить все, кроме небольшого количества нетривиальных ограничений в SQL.