О проблемах хранения деревьев в SQL базах данных вопрос можно не поднимать, просто сказать, что они есть.
Прежде всего посмотрим как выглядят деревья Nested Sets, как они организованы и в чем удобство их использования.

На схеме представлено дерево, описанное по всем правилам метода "Вложенных множеств". Квадратами обозначены узлы дерева, синие цифры в верхнем правом и верхнем левом углах узла - уровень и уникальный идентификатор соответственно, а красные цифры в нижних углах - это левый и правый ключ. Именно в этих двух цифрах - левом и правом ключе заложена вся информация о дереве. И если информацию о ключах занести в базу данных, то работа с деревом намного упрощается. Обратите внимание на то, в каком порядке проставлены эти ключи. Если мысленно пройтись по порядку от 1 до 32, то вы обойдете все узлы дерева слева направо. Фактически это путь обхода всех узлов дерева слева направо.
При использовании такой структуры дерева каталогов, очень сильно упрощается выборка определенных элементов, таких как родительская ветка, подчиненные узлы, вообще вся "ветка" в которой участвует наш узел. В общем все гораздо проще увидеть на практике:
Создадим таблицу, где мы будем хранить наше дерево (1):
Где:
Теперь определим, какие данные мы можем из неё (таблицы) выбрать:
1. Собственно само дерево (2):
В итоге, после небольшой обработки (в которой level играет роль множителя отступа), получим следующий список:
2. Выбор подчиненных узлов (за отправной узел возьмем "Узел 7" его ключи [left_key], [right_key] и уровень [level]) (3):
В итоге получаем:
| • • • Узел 7 • • • • Узел 12 • • • • Узел 13 • • • • Узел 14 |
![]() |
3. Выбор родительской "ветки" (4):
В итоге получаем:
| • Узел 1 • • Узел 3 • • • Узел 7 |
![]() |
4. Выбор ветки в которой участвует наш узел (5):
В итоге получаем:
| • Узел 1 • • Узел 3 • • • Узел 7 • • • • Узел 12 • • • • Узел 13 • • • • Узел 14 |
![]() |
В общем, использование в условии запроса ключей узла можно выбрать любые данные связанные с этим узлом.
Единственным затруднением может возникнуть выборка родительского узла, чтобы его получить можно сделать запрос (6):
Правда, такой метод может показаться довольно громоздким, поэтому, для удобства, часто добавляют еще одно поле в таблицу - parent_id - в котором хранится идентификатор родительского узла.