我们目前正在构建一个包含各种权限的分类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()函数,感觉这是正确的方法,但问题仍然存在。
答案 0 :(得分:1)
如果您需要在树中对一组节点进行排序,并在树中维护无限数量的级别,我是否可以建议使用预先排序的树遍历?
有关示例实现,请参阅http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/。
重点是您为每个节点维护左右值。您还可以为每个节点维护一个深度列,它可以告诉它所在树的哪个级别。您可以使用这些左右值按树中的顺序对节点进行排序,并使用深度值仅选择给定的树的层数。
这种方法唯一值得注意的缺点是,在更改节点结构时,必须主动维护这些左右值。
答案 1 :(得分:0)
根据我的经验,使用嵌套集模型并不是必需的,除非你期望一些非常繁忙的流量。我不确定你究竟需要什么样的层次结构,但我建议检查一个简单的父子表是否在其前面有一个缓存是不够的,它更容易维护和使用
同样,这当然取决于您的应用程序以及您对性能问题的担忧程度。
答案 2 :(得分:0)
在黑暗中进行刺穿,因为根据定义,嵌套的树集数据已经排序,听起来你需要将数据转换成另一种格式(通常是平面格式)才能对其进行排序。实现这一目标的最简单方法是简单地处理数据,随时创建平面数据集。
您在SQL中已经有一些选项。如果我的术语正确,按左侧ID排序可以按顺序进行遍历。这通常是人们在列出集合树时所需要的,因为它在扁平化为列表时是有意义的。我将在SQL中试验ORDER BY
子句;例如,按深度参数排序将为您提供级别顺序遍历。尝试将其与node.name
结合使用。