Я использую похожий, но не совсем тот же подход, который также сохраняет ссылку на родителя у ребенка; это облегчает построение древовидной структуры из данных. Если это полезно, я могу опубликовать код для извлечения данных в дерево на PHP.
@ Marc, описанная структура данных не обязательно для выполнения операций над множествами; это просто облегчает работу со структурой. Если вы хотите получить целое дерево данных, и каждая запись просто хранит указатель на родительскую запись, то вам нужно рекурсивно запросить базу данных, чтобы получить полное дерево данных. Если вы используете описанный там подход, то вы можете извлечь весь набор одним запросом.
Редактировать: вот код, который строит древовидную структуру, ЕСЛИ вы поддерживаете дочернюю -> родительскую ссылку, а также lft / right. Я предпочитаю делать это, потому что на самом деле это все еще быстрее, если вы хотите получить только прямые потомки одного уровня дерева.
Я пытался раздеть это, чтобы продемонстрировать основы, поэтому могут быть некоторые опечатки и т. Д., Но вы должны понять. Ключевые части
- Порядок запроса "lft ASC", таким образом вы всегда будете обрабатывать родительский узел перед его дочерними элементами.
- Сохранить ссылку на каждый узел по идентификатору; таким образом, любой дочерний элемент этого узла может легко найти его и добавить себя в родительский.
- Итерация по результатам, сохранение ссылки для каждого по идентификатору (как указано выше) и добавление этого узла к дочерним элементам его родителя.
В любом случае, вот код -
<?php
$children = mysql_query('SELECT * FROM nested_category ORDER BY lft ASC');
/* Get the first child; because the query was ordered by lft ASC, this is
the "root" of the tree */
$child = mysql_fetch_object($children);
$root = new StdClass;
$root->id = $child->folderID;
$root->children = array();
/* Store a reference to the object by the id, so that children can add
themselves to it when we come across them */
$objects = array($root->id => $root);
/* Build a tree structure */
while ($child = mysql_fetch_object($children)) {
/* Create a new wrapper for the data */
$obj = new StdClass;
$obj->id = $child->id;
$obj->children = array();
/* Append the child to the parent children */
$parent = $objects[$child->parent];
$parent->children[] = $obj;
$objects[$obj->id] = $obj;
}