Рекурсия Mysql?

Рассмотрим таблицу, подобную этой:

   folders_table
   -----------------------
      INT id_folder
      INT id_folder_parent
      VARCHAR folder_name

Что хранит простую структуру каталогов. Как я могу получить все подкаталоги каталога с одним запросом SELECT?

Ответы

Ответ 1

Возможно, но вам нужно изменить структуру базы данных; После внесения изменений вы можете получить дерево любой глубины в одном запросе. Запросы немного сложнее, но это все еще довольно просто.

Ответ 2

Со структурой таблицы, которую вы показали, это не может быть сделано с MySQL, поскольку она не поддерживает рекурсивные запросы

Ответ 3

С MySql/MariaDB вы можете использовать движок Open Query Graph (http://openquery.com/graph/doc), который является плагином mysql, который позволяет создавать специальные где вы устанавливаете отношения, в основном parentId и childId.

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

Он обрабатывает не только дерево (рекурсивные отношения 1-n), но и структуры графических данных (рекурсивные отношения nm) с весом (например, подумайте, что вы хотите сохранить права собственности компаний, компания может иметь несколько дочерних компаний и может также иметь несколько акционеры).

Ответ 4

Другой вариант - сохранить как глубину node, так и сохранить идентификатор для полного пути каждого node и использовать оба эти критерия.

Способ хранения XML-узлов в реляционной базе данных следующий:

SELECT id,value FROM element e1
INNER JOIN element e2 ON (e2.id=e1.parent_id AND name='friend')
WHERE e1.depth>4 AND e1.path like 'root[1]/users[1]/user:dana[1]/public[1]%'

В этом примере у меня есть поле для имени node и интеркатора в квадратных скобках для повторяющихся узлов с тем же именем node на каждом уровне дерева.

Когда вы вставляете каждый node, вам нужно вычислить полный путь, следуя родителям до корня node (parent_id IS NULL), добавляя каждый уровень в массив, в то же время храните глубину путь.

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

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

Ответ 5

1, создайте новую таблицу. tree_folder(id, id_folder, tree_id) 2, создайте новую таблицу. tree(id, tree_json)

Таблица tree поддерживает полное дерево node. Например, следующее дерево с корнем node 1.

{
    "folder_id": 1,
    "parent_folder_id": 0,
    "children": [
      {
          "folder_id": 10,
          "parent_folder_id": 1,
          "children": null
      },
      {
          "folder_id": 11,
          "parent_folder_id": 2,
          "children": null
      }
    ]
}

В таблице содержится эта строка.

[id, tree_json]
[1, "xxxxx"]

Затем поддерживайте связь между node и деревом. Как видите, дерево содержит node 1, 10, 11. Тогда у нас есть таблица tree_folder.

[id, folder_id, tree_id]
[1,  1        ,  1]
[2,  10       , 1]
[3,  11       , 1]

Когда вам нужно получить папку 10. просто получите от дерева, а затем обработайте его в своей программе.

Таким образом, вы просто выполняете рекурсию в памяти вместо mysql.

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