В реляционной базе данных я бы сохранил для каждого узла:
- Отец
- Чайлдс
- 1008 * предки *
С индексом на все и полным индексом на предках
Запрос на:
- все предки:
- O (log n) (найдите узел, тогда все готово)
- все потомки:
- O (полный индексный поиск по предкам) (зависит от базы данных)
- добавить новый узел / удалить узел (без дочерних элементов):
- O (1) для отца + предков
- O (войти n), чтобы найти отца
- обновить отцовских детей O (| отцовских детей |)
- переместить узел (сложный) :
- O (1), чтобы обновить отца
- O (войти n), чтобы найти старых / новых отцов
- дважды обновить дочерние элементы отца O (| дочерние элементы отца |)
- обновить предков всех потомков (простая замена): O (| потомки | * | глубина макс. Дерево |) (глубина-максимум: заменить и создать большую строку максимальной длины (глубина-максимум))
Общая сложность зависит от:
- Глубина дерева
- сбалансированное дерево?
- количество детей? (в среднем, макс ...)
- сложность работы в данной реляционной базе данных
Только для SELECT, эффективно, но сложно для обновлений.
На практике: работайте с деревом размером в ОЗУ (например, с memchaed, сохраняйте все в ОЗУ) и, если это невозможно, покупайте больше ОЗУ, чтобы "обрезать" дерево в меньших деревьях.
Все-потомки будут стоить дорого в любом случае, с поддеревьями вы можете иметь потомков с максимальной глубиной D, не имея их всех.
Вы «перепрыгиваете» из поддерева формы в поддерево: больше запросов, но быстрее и И перемещаете узел намного быстрее (нужно только обновить поддерево).