PHP:从嵌套集中排序数据

时间:2009-05-16 17:52:05

标签: php mysql sorting nested-sets

我们目前正在构建一个包含各种权限的分类MySQL表的网站,我们注意到嵌套集模型将针对此进行优化。虽然,我们遇到了一个非常严重的问题 - 嵌套集模型不允许任何排序,我们确实需要这种可能性。 我希望输出数据是数组(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);
        }
    }

非常感谢任何帮助。我用Google搜索了从嵌套集中对数据进行排序的不同方法,但没有任何好结果。

提前谢谢。

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

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

根据我的经验,使用嵌套集模型并不是必需的,除非你期望一些非常繁忙的流量。我不确定你究竟需要什么样的层次结构,但我建议检查一个简单的父子表是否在其前面有一个缓存是不够的,它更容易维护和使用

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

答案 2 :(得分:0)

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

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