11

深度没有限制。

如何获得结构化的分支甚至整个树?

定义来自这里:Managing Hierarchical Data in MySQL

4

5 回答 5

5

我不确定这是否完全符合您的要求,但值得注意的是,您可以通过使用GROUP_CONCAT并扩展“检索一个来自http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/的“单路径”示例

SELECT 
  GROUP_CONCAT(parent.name ORDER BY parent.lft ASC SEPARATOR '|') 
FROM nested_category AS node
     CROSS JOIN nested_category AS parent 
WHERE 
  node.lft BETWEEN parent.lft AND parent.rgt 
GROUP by node.id 
ORDER BY node.lft;

这将输出树中每个节点的路径。

注意nested_category AS node CROSS JOIN nested_category AS parent相当于nested_category AS node, nested_category AS parent

这使用指定字符串'|'作为分隔符,如果您想将其分解为路径元素数组并且您知道有一个字符串不在您的数据中,您可以指定它。

于 2012-08-31T02:41:52.340 回答
2

我使用了一种类似但不完全相同的方法,它也保留了对父级的引用;这使得从数据中构建树结构变得更加容易。如果这有用,我可以将用于提取数据的代码发布到 PHP 中的树中。

@Marc,所描述的数据结构不一定用于执行集合操作;它只是使使用结构更容易。如果要获取一整棵数据树,而每条记录只存储一个指向父记录的指针,则需要递归查询数据库以获取完整的数据树。如果您使用那里描述的方法,那么您可以在一个查询中提取整个集合。

编辑:如果您维护一个子 -> 父引用以及 lft/right 的东西,这是构建树结构的代码。我更喜欢这样做,因为如果您只想获取树的单个级别的直接后代,这种方式实际上会更快。

我试图将其剥离以展示要点,因此可能存在一些拼写错误等,但您应该明白这一点。关键部分是

  • 通过“lft ASC”对查询进行排序,这样您将始终在其子节点之前处理父节点。
  • 按 ID 存储对每个节点的引用;这样,该节点的任何子节点都可以轻松找到它并将自己添加到父节点。
  • 遍历结果,按 ID 存储每个节点的引用(如上)并将此节点添加到其父节点的子节点。

无论如何,这是代码 -

<?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;
}   
于 2010-04-10T15:57:26.123 回答
0

我必须告诉您有关使用 php.. 处理树结构的方法,无需递归。我认为您对标准 php 库 (SPL) 非常了解。您可以使用迭代器来解决您的问题。

http://www.php.net/~helly/php/ext/spl/

这是 SPL 文档的链接。以下是您上面的 Mysql 链接示例的一些解决方案:- 通过简单地从表中检索您的数组,您可以处理它们并显示为您的偏好

For :- 邻接表模型

您可以使用“RecursiveIteratorIterator”,它将显示所有结果,包括所有孩子。

如果你只想给孩子看。你可以使用“ParentIterator”

于 2010-04-15T05:06:18.597 回答
0

即使 mysql 端的数据结构有些奇特,仍然使用普通的查询方法检索数据。发出适当的 select 语句,循环遍历结果,并将其填充到 PHP 数组中。虽然我不知道您为什么要这样做,因为在 PHP 中执行 set 操作比在 MySQL 中要困难得多。

于 2010-04-07T14:20:19.007 回答
0

看看你的链接,我会用左连接来做。查看检索完整树的示例。

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4 FROM category AS t1 LEFT JOIN category AS t2 ON t2.parent = t1.category_id LEFT JOIN category AS t3 ON t3.parent = t2.category_id LEFT JOIN category AS t4 ON t4.parent = t3.category_id WHERE t1.name = 'ELECTRONICS';

对于要包含的每个层次结构级别,您都需要一个 LEFT JOIN。然后,结果可以由 php 解析为任何所需的数据结构。只是忽略NULL结果。

| ELECTRONICS | TELEVISIONS | TUBE | NULL |

| ELECTRONICS | TELEVISIONS | LCD | NULL |

| ELECTRONICS | TELEVISIONS | PLASMA | NULL |

| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |

| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS | NULL |

| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL |

当你有一个深层结构时,这将是一个更糟糕的方法,因为当需要连接许多表时,MySQL 连接需要很长时间才能执行。

我希望我没有误解你的问题。

于 2010-04-12T16:31:56.600 回答