1

我们目前正在构建一个网站,其中包含一个包含各种能力的分类 MySQL 表,我们注意到嵌套集模型将为此进行优化。虽然,我们遇到了一个非常严重的问题——嵌套集合模型不允许任何排序,我们确实需要这种可能性。我希望输出数据是array(id, name, depth),因为这个函数支持(虽然没有任何排序):

function tree()
{
    $query = 'SELECT node.id, node.name, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft';
    $result = mysql_query($query) or die(mysql_error());

    while($data = mysql_fetch_assoc($result))
    {
        $returnarray[] = $data;
    }

    return $returnarray;
}

我从一个函数开始,但不知道如何继续:

function tree_sorted()
{
    //Get data
    $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft';
    $result = mysql_query($query) or die(mysql_error());

    //Fetch gotten data
    while($data = mysql_fetch_assoc($result))
    {
        $fetched[$data['depth']][$data['id']] = array($data['name'], $data['parent']);
    }

    //Sort fetched data
    foreach($fetched as $i => $row)
    {
        asort($row);
        $sorted[$i] = $row;
    }

    //Merge sorted data (???)
    foreach($sorted as $i => $arr)
    {
        foreach($arr as $x => $row)
        {
            $returnarray[] = array('id' => key($row), 'name' => $row[0], 'depth' => $x);
        }
    }

任何帮助将不胜感激。我已经用谷歌搜索了从嵌套集中对数据进行排序的不同方法,但没有任何好的结果。

先感谢您。

编辑:现在我用 uasort() 函数尝试了一些感觉是正确的方法,但问题仍然存在。

4

3 回答 3

1

如果您需要对树中的一组节点进行排序,并在树中维护无限数量的级别,我是否建议使用预排序树遍历?

有关示例实现,请参见http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ 。

关键是您为每个节点维护一个左右值。您还可以为每个节点维护一个深度列,它告诉它在树的哪个级别。您可以使用这些左右值按节点在树中的顺序对节点进行排序,并使用深度值仅选择给定的树的层数。

这种方法唯一值得注意的缺点是在更改节点结构时必须主动维护这些左右值。

于 2009-06-02T15:09:39.440 回答
0

根据我的经验,使用嵌套集模型并不是真正必要的,除非您预计会有一些非常大的流量。我不确定你到底需要层次结构来做什么,但我建议检查一个简单的父子表是否足够,它前面有一个缓存,它更容易维护和使用

同样,这当然取决于您的应用程序以及您对性能问题的担忧程度。

于 2009-05-16T18:06:39.020 回答
0

在黑暗中尝试一下,因为嵌套的集合树数据根据定义已经排序,听起来您需要将数据转换为另一种格式(通常是平面格式)才能对其进行排序。实现这一点的最简单方法是简单地处理数据,随时创建一个平面数据集。

您在 SQL 中已经有了一些选项。如果我有正确的术语,按左 ID 排序可以让您按顺序遍历。这通常是人们在列出一个集合树时想要的,因为它在扁平化为一个列表时是有意义的。我将尝试使用ORDER BYSQL 中的子句;例如,按深度参数排序将为您提供级别顺序遍历。尝试将其与node.name.

于 2009-05-18T00:13:25.477 回答