Mysql рекурсия? - PullRequest
       3

Mysql рекурсия?

13 голосов
/ 03 декабря 2010

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

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

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

Ответы [ 5 ]

17 голосов
/ 03 декабря 2010

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

3 голосов
/ 03 декабря 2010

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

0 голосов
/ 24 января 2018

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

Таблица tree поддерживает целый узел дерева. Например, следующее дерево с корневым узлом 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"]

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

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

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

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

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

0 голосов
/ 25 января 2015

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

Способ хранения узлов 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]%'

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

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

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

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

0 голосов
/ 04 апреля 2013

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...