Представляя географические местоположения в приложении, проект базовой модели данных предлагает два четких варианта (или, может быть, больше?).
Одна таблица с самоссылающейся колонкой parent_id uk - london (london parent id = UK id)
или две таблицы с отношением один ко многим с использованием внешнего ключа.
Я предпочитаю одну таблицу со ссылками на себя, поскольку она легко позволяет охватить столько субрегионов, сколько требуется.
В общем, люди отклоняются от таблиц, на которые ссылаются сами, или они в порядке?
sql
database-design
ним чимпский
источник
источник
hierarchyid
тип.Necromancing.
Правильный ответ: это зависит от того, какой механизм базы данных и какой инструмент управления.
Давайте сделаем пример: у
нас есть таблица отчета,
и у отчета может быть родитель (пункт меню, например категория),
и у этого родителя может быть родитель (например, Центр прибыли)
и так далее до бесконечности.
Самый простой пример стандартного рекурсивного отношения, как и для любой самоссылающейся сущности / иерархии.
В результате получается таблица SQL-Server:
Но у вас возникает проблема:
когда вам нужно удалить пункт меню со всеми его подменю, вы НЕ МОЖЕТЕ установить delete-cascade, потому что Microsoft SQL-Server не поддерживает рекурсивное каскадное удаление (с другой стороны, PostGreSQL делает [но только если graph не циклический], в то время как MySQL вообще не нравится такая структура таблиц, потому что она не поддерживает рекурсивные CTE).
Таким образом, вы как бы взрывают целостность / функциональность удаления, делая обязательным выполнение таких функций в своем собственном коде или в хранимой процедуре (если ваша СУБД поддерживает хранимые процедуры).
Это, несомненно, взорвет любой вид полностью автоматического динамического импорта / экспорта данных, потому что вы не можете ни просто выполнить оператор удаления для всех таблиц в соответствии с отношениями внешних ключей (не являющихся ссылками), ни сделать простой выбор * и создать вставку для каждой строки в произвольном порядке.
Например, когда вы создаете сценарий INSERT с использованием SSMS, тогда SSMS не получит внешний ключ и, таким образом, действительно создаст операторы вставки, которые будут вставлять записи с зависимостями, прежде чем он вставит родительский элемент зависимости, что приведет к ошибке с ошибкой потому что внешний ключ на месте.
Тем не менее, в надлежащих системах управления базами данных (таких как PostgreSQL), с надлежащим инструментарием, это не должно быть проблемой. Просто поймите, что если вы много платите за свою СУБД (я смотрю на вас, Microsoft; Oracle =?) И / или на ее пояс для инструментов, это не значит, что она запрограммирована правильно. И при этом OpenSource (например, MySQL) не делает вас невосприимчивым к таким замечательным мелочам.
Дьявол кроется в деталях, как гласит старая поговорка.
Не то чтобы вы не могли обойти такие проблемы, но я бы не стал этого рекомендовать, если ваша система будет сложной (например, 200+ таблиц).
Кроме того, в обычной коммерческой обстановке (как изображено Дилбертом) вам просто не дадут этого времени.
Гораздо лучшим подходом, хотя и более сложным, будет закрытие таблицы.
Это будет иметь дополнительный бонус, что он также работает на MySQL.
Как только вы реализуете функцию замыкания один раз, она будет работать в дополнительных местах практически за короткое время.
источник
Это хорошая идея, если отношения на самом деле иерархические, а не сетевые (например, спецификация - это сетевые, а не иерархические).
Это может быть медленным, чтобы запросить. Чтобы ускорить процесс, вы можете использовать таблицу закрытия.
http://karwin.blogspot.ca/2010/03/rendering-trees-with-closure-tables.html
источник