问题
设计表结构存储树形结构数据时,一般使用 parentid 来记录当前节点的父id。
表结构如下所示(以mysql为例)
create table test ( id varchar(30) collate utf8mb4_general_ci default '' not null primary key, name varchar(100) collate utf8mb4_general_ci null, parentid varchar(30) collate utf8mb4_general_ci null comment '父分类id' ) comment 'test';
查询出全部数据后通过每个节点各自的 parentid 就能够构造出整棵树。
但是,有些时候只想找到某个节点下的所有子节点,如果还是要查全表后构造整棵树再去查找目标节点,就显得很繁琐
如何解决
方法1:使用 mysql 变量 + 函数
查询目标节点以及所有子节点,返回所有节点id,用【,】拼接
select group_concat(id) from (select @ids as id, (select @ids := group_concat(id) from test where find_in_set(parentid, convert(@ids using utf8mb4) collate utf8mb4_0900_ai_ci) ) as childrenid from test, (select @ids := '节点id') var where @ids is not null) t
同理,使用该方法还可以用来查询目标节点以及所有父节点
select group_concat(id) from (select @id as id, (select @id := parentid from test where id = convert(@id using utf8mb4) collate utf8mb4_0900_ai_ci) as pid from test, ( select @id := '节点id') var where @id is not null) t
方法2:维护一个 path 字段
方法1的查询语句其实不好理解,不便后期维护。
(经评论区提醒,如果id之间存在包含关系的话,就不适用了)如果id字段长度固定的话,可以给表新增一个path字段。
create table test ( id varchar(30) collate utf8mb4_general_ci default '' not null primary key, name varchar(100) collate utf8mb4_general_ci null, parentid varchar(30) collate utf8mb4_general_ci null comment '父分类id', path varchar(500) null comment 'id路径,逗号隔开' ) comment 'test';
path字段维护当前节点的所有父节点id,用【,】拼接
比如c节点的父节点是b,b节点的父节点是a,a是根节点
那么
- c节点的path字段就为:a节点id,b节点id,c节点id
- b节点的path字段就为:a节点id,b节点id
- a节点的path字段就为:a节点id
然后根据path字段模糊查询便可以找到目标节点以及子节点了
select id from test where path like ‘%节点id%'
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论