PHP+MySQL 无限级分类的两种实现方案
2017-01-04 10:30
573 查看
方案一:
表结构:
id int primary key auto_increment;
name varchar(40);
pid int default 0; #父类id,默认值为0
顶级分类的 pid 默认就是0了。当我们想取出某个分类的子分类树的时候,基本思路就是递归,当然,出于效率问题不建议每次递归都查询数据库,通常的做法是先将所有分类取出来,保存到PHP数组里,再进行处理,最后还可以将结果缓存起来以提高下次请求的效率。
优点:关系清楚,修改上下级关系简单
缺点:使用PHP处理,如果分类信息数量庞大,效率也会降低
方案二:
在表字段中增加一个 path 字段
id int primary key auto_increment;
name varchar(40);
pid int default 0; #父类id,默认值为0
path varchar(255); #记录从根分类到父类的路径,eg:0-1-5,数字是id
示例数据:
id name pid path
1 电脑 0 0
2 手机 0 0
3 笔记本 1 0-1
4 超级本 3 0-1-3
5 游戏本 3 0-1-3
这种方式,假设我们要查询电脑下的所有后代分类,只需要一条sql语句:
select id,name from category where path like ( select concat(path,'-',id,'%') path from category where id=1 );
优点:查询容易,效率高,path字段可以加索引。
缺点:更新节点关系麻烦,需要更新所有后辈的path字段。
方案一的样例代码:
<?php
$addrs = array(
array('id'=>1, 'name'=>'中国', 'pid'=>0),
array('id'=>2, 'name'=>'河南', 'pid'=>1),
array('id'=>3, 'name'=>'郑州', 'pid'=>2),
array('id'=>4, 'name'=>'洛阳', 'pid'=>2),
array('id'=>5, 'name'=>'安阳', 'pid'=>2),
array('id'=>6, 'name'=>'林州', 'pid'=>5),
array('id'=>7, 'name'=>'安阳县', 'pid'=>5),
array('id'=>8, 'name'=>'内黄', 'pid'=>5),
array('id'=>9, 'name'=>'滑县', 'pid'=>5),
array('id'=>10, 'name'=>'城郊乡', 'pid'=>6),
array('id'=>11, 'name'=>'湖南', 'pid'=>1),
array('id'=>12, 'name'=>'长沙', 'pid'=>11),
array('id'=>13, 'name'=>'湘潭', 'pid'=>11),
array('id'=>14, 'name'=>'岳麓区', 'pid'=>12),
);
// 查询子树
function get_childs($id)
{
global $addrs;
$ret = array();
foreach($addrs as &$addr) // 此处使用 & 运算符,提高效率
{
if($addr['pid'] == $id)
{
$addr['children'] = get_childs($addr['id']);
$ret[] = $addr;
}
}
return $ret;
}
// test code
echo '<pre>';
print_r( get_childs(1) );
echo '<hr/>';
print_r($addrs);
表结构:
id int primary key auto_increment;
name varchar(40);
pid int default 0; #父类id,默认值为0
顶级分类的 pid 默认就是0了。当我们想取出某个分类的子分类树的时候,基本思路就是递归,当然,出于效率问题不建议每次递归都查询数据库,通常的做法是先将所有分类取出来,保存到PHP数组里,再进行处理,最后还可以将结果缓存起来以提高下次请求的效率。
优点:关系清楚,修改上下级关系简单
缺点:使用PHP处理,如果分类信息数量庞大,效率也会降低
方案二:
在表字段中增加一个 path 字段
id int primary key auto_increment;
name varchar(40);
pid int default 0; #父类id,默认值为0
path varchar(255); #记录从根分类到父类的路径,eg:0-1-5,数字是id
示例数据:
id name pid path
1 电脑 0 0
2 手机 0 0
3 笔记本 1 0-1
4 超级本 3 0-1-3
5 游戏本 3 0-1-3
这种方式,假设我们要查询电脑下的所有后代分类,只需要一条sql语句:
select id,name from category where path like ( select concat(path,'-',id,'%') path from category where id=1 );
优点:查询容易,效率高,path字段可以加索引。
缺点:更新节点关系麻烦,需要更新所有后辈的path字段。
方案一的样例代码:
<?php
$addrs = array(
array('id'=>1, 'name'=>'中国', 'pid'=>0),
array('id'=>2, 'name'=>'河南', 'pid'=>1),
array('id'=>3, 'name'=>'郑州', 'pid'=>2),
array('id'=>4, 'name'=>'洛阳', 'pid'=>2),
array('id'=>5, 'name'=>'安阳', 'pid'=>2),
array('id'=>6, 'name'=>'林州', 'pid'=>5),
array('id'=>7, 'name'=>'安阳县', 'pid'=>5),
array('id'=>8, 'name'=>'内黄', 'pid'=>5),
array('id'=>9, 'name'=>'滑县', 'pid'=>5),
array('id'=>10, 'name'=>'城郊乡', 'pid'=>6),
array('id'=>11, 'name'=>'湖南', 'pid'=>1),
array('id'=>12, 'name'=>'长沙', 'pid'=>11),
array('id'=>13, 'name'=>'湘潭', 'pid'=>11),
array('id'=>14, 'name'=>'岳麓区', 'pid'=>12),
);
// 查询子树
function get_childs($id)
{
global $addrs;
$ret = array();
foreach($addrs as &$addr) // 此处使用 & 运算符,提高效率
{
if($addr['pid'] == $id)
{
$addr['children'] = get_childs($addr['id']);
$ret[] = $addr;
}
}
return $ret;
}
// test code
echo '<pre>';
print_r( get_childs(1) );
echo '<hr/>';
print_r($addrs);
相关文章推荐
- PHP无限级分类简单实现方法
- [Language-php]php+mysql无限级分类(非递归)
- php无限极分类实现的两种解决方法
- PHP+MySQL无限级分类(非递归)
- PHP连接MYSQL实现简单的无限极分类
- php+mysql无限级分类(非递归)
- php mysql实现无限级分类 | 树型显示分类关系
- php无限级分类实现代码(递归方法)
- mysql 无限级分类实现思路
- 无限级分类 for PHP+Mysql
- php+mysql无限级分类的代码
- php+mysql无限级分类(非递归)
- 采用Jquery+Ajax+PHP+MySQL实现分类列表管理 - 上篇
- PHP MySQL实现无限级分类|树型显示分类关系
- php+mysql无限级分类(非递归)
- php+mysql无限级分类(非递归)
- php+mysql实现的无限极分类
- PHP+MYSQL实现无限级分类管理
- Php无限级栏目分类读取的实现代码
- PHP无限级分类实现程序