【发布时间】:2010-04-07 01:12:43
【问题描述】:
【问题讨论】:
标签: php mysql nested-sets
【问题讨论】:
标签: php mysql nested-sets
我不确定它是否完全符合您的要求,但值得注意的是,您可以通过使用 GROUP_CONCAT 并扩展,在 MySQL 中获得整个树,每个路径一行,每个路径作为字符串,如下所示关于来自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。
这使用指定字符串'|' 作为分隔符,如果你想将它分解成一个路径元素数组并且你知道有一个字符串不在你的数据中,你可以指定它。
【讨论】:
我使用了一种类似但不完全相同的方法,该方法还保留了对子项中父项的引用;这使得从数据中构建树结构变得更加容易。如果这有用,我可以将用于提取数据的代码发布到 PHP 中的树中。
@Marc,所描述的数据结构不一定用于执行集合操作;它只是使使用结构更容易。如果要获取一整棵数据树,而每条记录只存储一个指向父记录的指针,则需要递归查询数据库以获取完整的数据树。如果您使用那里描述的方法,那么您可以在一个查询中提取整个集合。
编辑:这是构建树结构的代码,如果您维护一个子 -> 父引用以及 lft/right 的东西。我更喜欢这样做,因为如果您只想获取树的单个级别的直接后代,这种方式实际上仍然更快。
我已尝试将其剥离以演示基本要素,因此可能存在一些拼写错误等,但您应该明白这一点。关键部分是
无论如何,这是代码 -
<?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;
}
【讨论】:
即使 mysql 端的数据结构有些奇特,仍然可以使用普通查询方法检索数据。发出适当的 select 语句,循环遍历结果,并将其填充到 PHP 数组中。虽然我不知道你为什么要这样做,因为在 PHP 中执行 set 操作比在 MySQL 中要困难得多。
【讨论】:
看看你的链接,我会用左连接来做。查看检索完整树的示例。
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 连接需要很长时间才能执行。
希望我没有误解你的问题。
【讨论】:
我必须告诉您有关使用 php.. 无需递归即可处理树结构的方法。我认为您对标准 php 库 (SPL) 非常了解。您可以使用迭代器来解决您的问题。
http://www.php.net/~helly/php/ext/spl/
这里是 SPL 文档的链接。以下是您上面的 Mysql 链接示例的一些解决方案:- 通过简单地从表中检索您的数组,您可以处理它们并显示为您的偏好
对于:- 邻接表模型
您可以使用“RecursiveIteratorIterator”,它将显示所有结果,包括所有子项。
如果你只想给孩子们看。您可以使用 “父迭代器”
【讨论】: