Как-то помнится на четвертом курсе я писал блог на CodeIgniter (PHP) в качестве ВКР, тоже использовал parent_id. Вот там выверты были с рекурсивным составлением запросов для выборки веток…
Очень ценные замечания! Честно говоря, не задумывался об этом. Исходил из того, что ORM в различных фреймворках зачастую оперируют таблицами, оставляя выбор добавления ключей за пользователем. Теперь будет пища для размышлений и реализации обозначенного вами в следующих версиях моей библиотечки :)
Ссылка на самого себя действительно позволяет без костылей формировать запросы на выборку ветки. Такой записью, если хотите, помечается возможность ноды быть как предком, так и потомком.
Фишка как раз в уходе от поля parent, в уходе от рекурсии и большого количества join-ов. Обратите внимание, что любой из приведенных запросов использует всего лишь один join. И дерево по такой таблице связей строится достаточно легко.
А что касается проблем с целостностью, то я думаю, что это зависит от реализации интерфейса по работе с такой системой. Если интерфейс правильно организован, пользователь не сможет нагородить огород и всё поломать.
Можно, конечно, добавить внешние ключи. Однако они потеряют особый смысл, если у нас, например, будет поле level для уровня вложенности, которое при перестроении дерева всё равно надо будет обновлять. Или, к примеру, мы захотим удалить всю ветку комментариев или тех же страниц. От кастомного запроса, наподобие приведенных, в таком случае не уйти.
Так в таблице pages_treepath оно ведь дублироваться будет. А так ведь страницы, категории и прочие — сортируемые ведь вещи. И к связям сортировка имеет лишь то отношение, что по позиции можно выбрать предыдущие или следующие элементы (prev siblings, next siblings).
Нет, таблица treepath хранит все связи. То есть каждый предок хранит информацию о своих дочерних элементах. В данном случае получится следующая таблица:
В статье забыл об этом упомянуть. За порядок может отвечать поле position, которое следует добавить в таблицу pages. От нуля и до бесконечности. В своей реализации я так и сделал.
parent
, в уходе от рекурсии и большого количества join-ов. Обратите внимание, что любой из приведенных запросов использует всего лишь один join. И дерево по такой таблице связей строится достаточно легко.А что касается проблем с целостностью, то я думаю, что это зависит от реализации интерфейса по работе с такой системой. Если интерфейс правильно организован, пользователь не сможет нагородить огород и всё поломать.
level
для уровня вложенности, которое при перестроении дерева всё равно надо будет обновлять. Или, к примеру, мы захотим удалить всю ветку комментариев или тех же страниц. От кастомного запроса, наподобие приведенных, в таком случае не уйти.pages_treepath
оно ведь дублироваться будет. А так ведь страницы, категории и прочие — сортируемые ведь вещи. И к связям сортировка имеет лишь то отношение, что по позиции можно выбрать предыдущие или следующие элементы (prev siblings, next siblings).position
, которое следует добавить в таблицуpages
. От нуля и до бесконечности. В своей реализации я так и сделал.