#database #tree
#База данных #дерево
Вопрос:
Мне нужно создать таблицы MySQL, которые представляют древовидную структуру, подобную этой:
Root
|- Chapter 1
| |- Chapter 1.1
| | |- Article 1.1.1
| | |- Article 1.1.2
| |- Article 1.2
| |- Chapter 1.3
| |- Chapter 1.3.1
| | |- Article 1.3.1.1
| | |- Article 1.3.1.2
| |- Article 1.3.2
| |- Article 1.3.3
|- Chapter 2
|-Chapter 2.1
| |- ...
|- Chapter 2.2
|- ...
Проще говоря, существует два типа сущностей: глава и статья. Статья — это наименьший объект, под которым нет дочернего элемента, в то время как глава может содержать подраздел или статьи в качестве дочернего объекта. Каждый объект будет иметь идентификатор и имя.
Порядок дочерних элементов не имеет установленного правила, это может быть глава, затем статья, затем снова глава.
Другая проблема заключается в том, что когда глава перемещается из одной главы в другую, все дочерние элементы также должны быть соответствующим образом перемещены. Например, когда я перемещаю главу 1.3.1 в раздел 1.1 (таким образом, глава 1.3.1 становится главой 1.1.3), тогда статьи 1.3.1.1 и 1.3.1.2 также должны быть перемещены и стать статьями 1.1.3.1 и 1.1.3.2. И в то же время статьи 1.3.2 и 1.3.3 станут статьями 1.3.1 и 1.3.2 соответственно.
Итак, я спрашиваю, как спроектировать таблицу базы данных так, чтобы представить эти отношения? И как SQL будет выглядеть для добавления нового элемента / удаления элемента и перестановки элементов? (Я могу использовать Ajax для обработки взаимодействия с перемещением и использовать PHP для создания этой иерархической нумерации)
Кроме того, поскольку дерево обычно довольно длинное, я хочу избежать обновления всех элементов только потому, что перемещен только один элемент. (Не уверен, что это желание технически возможно.)
Ответ №1:
Лучшая информация, которую я нашел о представлении древовидных структур в базе данных, содержится в книге Джо Селко «Деревья и иерархии в SQL для Smarties«.
Вероятно, вы можете найти достаточно информации в Интернете, но я бы рекомендовал получить книгу, я нашел ее очень полезной при реализации иерархии вложенных множеств.
Вы можете использовать список смежности или вложенные наборы для моделирования дерева в базе данных, я предполагаю, что вы используете список смежности (где каждая запись имеет parent
атрибут)
Если вы хотите иметь возможность перемещать целые поддеревья от одного родительского элемента к пыльнику, то это должно быть так же просто, как изменить parent_id
(или любой другой PK, который вы используете), чтобы ссылаться на нового родительского элемента. Модель вложенного набора требует изменений во всех узлах при перемещении поддерева.
Однако с вложенным набором проще выполнять другие операции, например, выбирать все дочерние узлы под определенным родительским. Это может быть сложнее с моделью списка смежности, но стало проще с появлением рекурсивного CTE.
Если вы не беспокоитесь о порядке содержимого, я бы не стал хранить номера глав вместе с вашими данными. Применяйте их при выборе данных, и тогда вам не придется обновлять каждый узел при изменении вашего дерева.
Комментарии:
1. спасибо за рекомендацию вашей книги. К сожалению, я не могу дождаться, когда эта книга решит мою проблему. Я попытаюсь использовать методы, которые вы предложили. Да, номера глав будут сгенерированы PHP вместо сохранения в DB