mysql 单标递归_【mysql】递归解决无限级分类的问题

小弟手中有分类3406条,存在category表中。现在用递归解决分类,做成select,如下图:

下面是PHP代码,但是生成select后有错误:

// $result是从数据库中读出的二维数组

$result = array();

while (($row = $info->fetch_array(MYSQLI_ASSOC)) != false) {

// 改变数组的索引为分类的id

$result[$row['id']] = $row;

}

$str = '';

$str .= "";

foreach ($result as $value) {

if ($value['parent_id'] == 0) {

$str .= "{$value['title']}";

$str .= get_children($value['id'], $result, 1);

}

}

$str .= "";

function get_children($id, &$result, $index) {

$str = '';

foreach ($result as $key => $value) {

if ($id == $value['parent_id']) {

$str .= "".str_repeat('---', $index)."{$value['title']}";

$str .= get_children($value['id'], $result, $index + 1);

unset($result[$value['id']]); // 存在并且去掉这个以为数组

//echo count($result).'
';

}

}

return $str;

}

// 打印出select

echo $str;

上面代码中,去掉unset执行最后的结果是对的,但是执行时间一般在八九秒。我的想法是存在这一条后把这一条从result结果集中去掉,这样的话以后循环的时候减少循环的次数,然后就能减少执行的时间,但是执行的结果是不对的,只存在省下面的一个地市,其余的地市没有了,研究了半天,也没有发现哪里错,请大神指正。

PS: 1。第一次发帖,不怎么会用,请谅解小弟。

2。有没有更好的办法递归3400多个分类。。

3.谢谢。。

回答

关系数据库中的无限深度树状关系的表示有两种常见方案:

edge list tree(又写作adjacency list,即邻接表)

一行的表示类似于(子元素id, 父元素id)

nested set tree(即左右值)

一行的表示类似于(当前元素左值, 当前元素右值)

相信楼主用的是前者,这样的坏处是需要递归查询。而后者更易于查询,一条sql即可搞定,见@沙渺 的这篇文章。

针对lz的问题,如果嵌套关系表示使用的是左右值方法,拿到全量数据的前提下,在PHP中也可以用O(n)方式迭代数据得到所有需要的子节点和深度等数据,非常简单。

如果只是需要在前端使用这些树状数据,那么公子的方案是最简单的,比用数据库邻接表、服务器端递归遍历简单多了。

关于nested set:

如果用引用来处理的话,效率会增加很多,参照这里

但是下拉菜单显示3400条数据,用户也没发去点选啊,所以这个可以不从算法上来考虑,而应该从应用设计上来解决,例如利用多级关联下级菜单的懒加载来实现更为合理,而对于分隔的小数据,上述的普通递归也足够用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值