Как сохранить каталог / иерархию / древовидную структуру в базе данных?

Как сохранить структуру каталога / иерархии / дерева в базе данных? А именно сервер MSSQL.

@olavk: не похоже, что вы видели мой собственный ответ. Способ, которым я использую, лучше, чем рекурсивные запросы:)

п.С. С. Это путь!

8 ответов


здесь много способов для хранения иерархий в базах данных SQL. Какой из них выбрать, зависит от того, какой продукт СУБД вы используете и как будут использоваться данные. Поскольку вы использовали тег MSSQL2005, я думаю, вам следует начать рассматривать модель "список смежности"; если вы обнаружите, что она не работает хорошо для вашего приложения, то посмотрите на Вадим Tropashko это что выделяет разницы между моделями с фокусом на множественном представлении характеристики.


Если использование Sql Server 2008 является опцией: возможно, вам следует проверить new hierarchyid тип данных.


Это больше закладок для меня, чем вопрос, но это может помочь вам тоже. Я использовал этой статьи подход для хранения структуры каталога / дерева в базе данных.

в статье также есть некоторые полезные фрагменты кода.

надеюсь, что это помогает.

Я никоим образом не связан с этим сайтом


существует также вложенная модель деревьев, которая имеет некоторые преимущества перед моделью ParentID. См.http://www.evanpetersen.com/item/nested-sets.html и http://falsinsoft.blogspot.nl/2013/01/tree-in-sql-database-nested-set-model.html


вы используете SQL Server 2005? рекурсивные запросы сделайте запрос иерархических данных намного более элегантным.

Edit: я думаю, что материализованные пути немного взломать. Путь содержит ненормализованные избыточные данные, и вы должны использовать триггеры или что-то еще, чтобы обновлять их. Например. если узел изменяет родителя, все поддерево должно иметь обновленные пути. И запросы поддерева должны использовать некоторое уродливое соответствие подстроки, а не элегантный и быстрый присоединяться.


Я столкнулся с аналогичной проблемой с одним из моих проектов. У нас была огромная иерархия, которая будет расти вечно. Мне нужно было быстро пройти его, а затем найти нужную группу после некоторых сложных проверок. Вместо того, чтобы идти в SQL Server и чесать голову, как я могу сделать это эффективно, когда я знал, что рекурсивные запросы являются единственным жизнеспособным решением. Но вы действительно знаете, есть ли какая-либо оптимизация вообще возможна в рекурсивных запросах. Есть ли гарантия, что ваш иерархия не будет увеличиваться в будущем, и в один прекрасный день вы обнаружите, что ваши рекурсивные запросы слишком медленны для использования в производстве?

Итак, я решил дать шанс Neo4J. Это графическая база данных со многими полезными алгоритмами, удивительно быстрым обходом с достойной документацией и примерами. Сохраните иерархию в Neo4J и получите доступ к иерархии с помощью службы бережливости (или чего-то еще). Да, вам придется написать код, который будет интегрировать ваши SQL-запросы с Neo4J, но вы будут иметь масштабируемое и перспективное решение.

надеюсь, что вы найдете это полезным.


вопрос похож на этот вопрос, который был закрыт. Я нашел ответы на оба вопроса очень полезными в моих занятиях, и они в конечном итоге привели меня к руководству MongoDB, в котором представлены 5 различных способов моделирования древовидных структур: https://docs.mongodb.com/manual/applications/data-models-tree-structures/

хотя MongoDB не является реляционной базой данных, представленные модели применимы к реляционным базам данных, а также к другим форматам, таким как формат JSON. Вам явно нужно выяснить, какая модель правильная, основываясь на представленных плюсах/минусах.

автор этого вопроса нашел решение это объединило как родительские, так и материализованные модели путей. Поддержание глубины и родителя может представлять некоторые проблемы (дополнительная логика, производительность), но для определенных потребностей есть явные недостатки. Для моего проекта материализованные пути будут работать лучше всего, и я преодолел некоторые проблемы (сортировка и длина пути) с помощью методов из этой статьи.


типичным способом является таблица с внешним ключом (например, "ParentId") на себя.