Ответ 1
Как всегда: лучшего решения нет. Каждое решение делает разные вещи проще или сложнее. Правильное решение для вас зависит от того, какую операцию вы будете делать больше всего.
Наивный подход с parent-id:
Плюсы:
-
легко реализовать
-
легко перемещать большое поддерево в другой родительский
-
Вставить дешево
-
Необходимые поля, напрямую доступные в SQL
Минусы:
-
Получение целого дерева рекурсивно и поэтому дорого
-
найти всех родителей тоже дорого (SQL не знает рекурсии...)
Измененный обход дерева предзаказов (сохранение начальной и конечной точки):
Плюсы:
-
Получение всего дерева легко и дешево
-
Поиск всех родителей дешев
-
Необходимые поля, напрямую доступные в SQL
-
Бонус: вы также сохраняете порядок дочерних элементов в своем родительском классе
Минусы:
- Вставка/обновление может быть очень дорогостоящим, так как вам, возможно, придется обновлять множество узлов.
Сохранение пути в каждом Node:
Плюсы:
-
Поиск всех родителей дешев
-
Извлечение всего дерева дешево
-
Вставка дешевая
Минусы:
-
Перемещение цельного дерева дорого
-
В зависимости от того, как вы сохраняете путь, вы не сможете работать с ним непосредственно в SQL, поэтому вам всегда нужно извлекать и анализировать его, если вы хотите его изменить.
Я бы предпочел один из двух последних, в зависимости от того, как часто изменяются данные.
Смотрите также: http://media.pragprog.com/titles/bksqla/trees.pdf