Рекурсия 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.
То есть вы должны поддерживать структуру при записи данных, но запрос выполняется легко и быстро. Если запрос является частым, это работает отлично. Но если запись частая, просто используйте кеш вместо этого метода.