Опция № 1 гарантирует, что каждая страница
принадлежит одному и только одному другому
сущность, хотя отношения не могу
на самом деле должен быть принудительно установлен в качестве parentId
поле может указывать на несколько
место.
правый. С точки зрения теории отношений проблема заключается в том, что ваш столбец "parentId
" нарушает третью нормальную форму , поскольку его значение варьируется в зависимости от значения строки в parentType
(столбец без ключа) .
У вас не было бы правильно спроектированной базы данных, если бы в одном столбце мог содержаться чей-то номер телефона или их дата рождения в каждой строке, в зависимости от какого-либо другого флага. Это два разных факта о человеке, и каждый из них заслуживает отдельной колонки. Аналогичным образом, сохранение и site_id, или node_id в одном столбце приведет к одной и той же проблеме.
Еще один признак того, что это ошибочный дизайн, заключается в том, что вы не можете объявить ограничение внешнего ключа для указания или двух ссылочных таблиц.
Вариант №2 чище, но это
в основном говорят, что сайт
«принадлежит» двум ошибкам, а не
найденные страницы, и это, вероятно, плохо
практика.
Я понимаю, почему вы говорите, что из-за относится к соглашениям в Rails-подобных фреймворках. Но это условности; они не обязательно являются единственными отношениями, которые могут моделировать внешние ключи. Вы можете сделать так, чтобы одна сущность ссылалась ровно на одну другую сущность, в есть одна связь. В этом случае внешний ключ меняет направление.
Я бы сказал, что логически верно, что страница Error и страница Not Found принадлежат сайту, а не наоборот. И способ сделать их обязательными состоит в том, чтобы другой объект ссылался на эти страницы и применял ограничение NOT NULL
к этим ссылкам. Это то, что вы описали.
CREATE TABLE site (
. . .
error_page_id INT NOT NULL,
notfound_page_id INT NOT NULL,
FOREIGN KEY (error_page_id) REFERENCES pages (page_id),
FOREIGN KEY (notfound_page_id) REFERENCES pages (page_id)
);
Это отвечает вашим насущным потребностям, подлежит исполнению и находится в обычной форме.
@ NXC предлагает создать фиктивные узлы для страниц ошибок и не найденных. Несмотря на то, что это позволяет хранить эти узлы в иерархии узлов, оно не может обеспечить наличие на этих страницах сайта. То есть сайт может храниться без ссылок на эти узлы.
@ Тони Эндрюс предлагает сохранить два столбца на каждой странице site_id
и site_node_id
и добавить ограничение CHECK, чтобы гарантировать, что один из них не равен NULL. Кажется, это лучше, чем опция parent_id
/ parent_type
, но все равно не предлагает каких-либо принудительных мер, что на каждом сайте должна быть страница об ошибке и страница не найдена.