Поскольку вы рассматриваете подход SQL, вот несколько вещей, о которых стоит подумать.
Во-первых, насколько велики деревья? Для многих применений 10000 листов будут казаться большими. Тем не менее, это мало для базы данных. В любой приличной системе баз данных (например, в ноутбуке) вы должны хранить сотни тысяч или миллионы листов в памяти.
Что база данных покупает у вас по другим подходам:
- Не нужно беспокоиться о производительности памяти / диска. Когда данные перетекают на диск, вы не сильно снижаете производительность. Для сравнения рассмотрим, что происходит, когда хэш-таблица переполняет память.
- Возможность добавлять индексы для оптимизации производительности.
- Возможность «просто» изменить путь доступа к дереву путем изменения SQL
Одна из проблем стандартного SQL состоит в том, что вы можете представить узел дерева в виде простой пары:,,. Затем, с помощью простого соединения, вы можете перемещаться между родителями и листьями. Тем не менее, соединения накапливаются по мере продвижения вверх по дереву.
Вздох. Различные базы данных имеют разные решения для этого. SQL Server имеет рекурсивные CTE, которые позволяют вам обходить дерево. У Oracle есть другой подход к древовидным структурам.
Это начинает усложняться.
Возможно, лучшим подходом является назначение «листового» идентификатора на основе иерархии в дереве. Таким образом, если это бинарное дерево, то «10011» будет узлом в правой ветви, левой ветви, левой ветви, правой ветви, правой ветви. Там вы будете хранить информацию. , , например, есть ли у него дети и все остальное. Получить родителя легко, потому что вы можете просто обрезать последнюю цифру.
Вы можете видеть, как это обобщается на недвоичные деревья. Наличие любого количества детей может создать небольшую проблему.
Я полагаю, что это может быть связано с подходом "массива предков".
Пока я думаю об этом, я думаю, что это будет работать довольно хорошо. Затем я бы предложил вам определить отдельные хранимые процедуры для каждого требуемого действия:
usp_tree_FetchNode (NodeId)
usp_tree_GetParent (NodeId)
usp_tree_NodeDelete (NodeId)
usp_tree_FetchSubTree (NodeId)
и т. д. и т. д.
Хотя SQL на самом деле не поддерживает объектно-ориентированное программирование, вы все равно можете организовать свой код с помощью чистых соглашений об именах и хороших упаковщиков функций.
Я действительно думаю, что это может сработать и обеспечить довольно хороший метод для разработки кода. Одним приятным побочным эффектом является то, что вы можете анализировать дерево вне приложения, что может предложить будущие улучшения.