Дизайн таблицы базы данных для упорядоченного древовидного списка

#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