У вас возникает ощущение, что либо ENTRIES.survey_id
, либо QUESTIONS.survey_id
избыточны (вероятно, потому, что вы видите, что можно вывести одно или другое через сущность ANSWERS
).
На самом деле QUESTIONS
и ENTRIES
имеют идентифицирующие отношения с SURVEYS
(запись или вопрос могут не существовать без соответствующего опроса). Формально говоря, их первичный ключ должен включать ссылку внешнего ключа на родительскую таблицу SURVEYS
:
CREATE TABLE SURVEYS (
survey_id INT NOT NULL,
PRIMARY KEY (survey_id)
);
CREATE TABLE QUESTIONS (
question_id INT NOT NULL,
survey_id INT NOT NULL,
PRIMARY KEY (question_id, survey_id),
FOREIGN KEY (survey_id) REFERENCES SURVEYS(survey_id)
);
CREATE TABLE ENTRIES (
entry_id INT NOT NULL,
survey_id INT NOT NULL,
PRIMARY KEY (entry_id, survey_id),
FOREIGN KEY (survey_id) REFERENCES SURVEYS(survey_id)
);
Как интересное следствие, ваша таблица ANSWERS
должна* на самом деле также включать survey_id
в свои ссылки на внешние ключи, потому что это поле является частью первичного ключа как QUESTIONS
, так и ENTRIES
:
CREATE TABLE ANSWERS (
entry_id INT NOT NULL,
survey_id INT NOT NULL,
question_id INT NOT NULL,
PRIMARY KEY (entry_id, survey_id, question_id),
FOREIGN KEY (entry_id, survey_id)
REFERENCES ENTRIES(entry_id, survey_id),
FOREIGN KEY (question_id, survey_id)
REFERENCES QUESTIONS(question_id, survey_id)
);
Если это может помочь вам избавиться от ложного впечатления, что одно поле survey_id
является избыточным, учтите, что может существовать запись без ответа (например, при создании новой записи). В этой ситуации, очевидно, требуется ENTRIES.survey_id
.
* На самом деле это дополнительное поле обязательно для моделирования ограничения "ответ должен относиться к вопросу и записи, которые относятся к одному и тому же опросу".
person
RandomSeed
schedule
08.10.2013