最佳数据库无限分级快速查找所有子节点的方法

场景我们基本设计的表是这样的

temp表

id, name, parent_id

当我们查某个节点的所有子节点的时候,我们需要递归查询

id = 4

select * from temp where parent_id = 4

ids = [5,9,25]

select * from temp where parent_id in [5,9,25]

那么这种方法在层数达到一定层的时候势必带来性能问题,因为需要多次查询数据库,就算写存储过程,性能也是十分低下的。

快速查询方法如下:

改造表,添加chain_ids和level字段,用于记录某个子节点的所有父节点以及当前节点的深度,用逗号隔开,最后一个是自己的id

id,       name,        parent_id,       chain_ids          level

1         根菜单       null                   1                       0

2         管理员        1                      1,2                   1

3         业务            1                      1,3                   1

4         用户管理     2                     1,2,4                 2

5         角色管理     2                     1,2,5                 2

6         报表查询     3                     1,3,6                 2

7         系统参数     2                      1,2,7                2

8         业务日志     3                      1,3,8                2

比如上面的数据,需要快速查找管理员下所有子节点

1. 将所有数据按chain_ids排序,将得到如下排序

id,       name,        parent_id,       chain_ids          level

1         根菜单       null                   1                       0

2         管理员        1                      1,2                   1

4         用户管理     2                     1,2,4                 2

5         角色管理     2                     1,2,5                 2

7         系统参数     2                     1,2,7                2

3         业务            1                      1,3                   1

6         报表查询     3                     1,3,6                 2

8         业务日志     3                      1,3,8                2

2. 找到该节点(管理员)的chain_ids   ->    1,2

3. 找到同级比他大的数据的第一个   ->    1,3

4. 那么 大于1,2 小于 1,3 的所有数据就是1,2下的所有子节点

5. 同时chain_ids该列需要建索引

SQL即

SELECT *

FROM temp

WHERE

chain_ids > ‘1,2 ‘

AND chain_ids < (

SELECT chain_ids FROM temp WHERE chain_ids > ‘1,2‘ AND level = 1 LIMIT 1

)

注意,如果此处层级太多,可以考虑用64进制甚至256进制来存储chain_ids中的id列表

原文地址:https://www.cnblogs.com/kazetotori/p/9715247.html

时间: 2024-10-14 12:20:37

最佳数据库无限分级快速查找所有子节点的方法的相关文章

T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

-- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316--子节点 union all select b.Type_Id,b.ParentId,b.Type_Name  from  tab a,--子节点数据集  Sys_ParamType_V2_0 b  --父节点数据集 where a.ParentId=b.Type_Id  --子节点数据集.paren

[SQL]T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

-- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316--子节点 union all select b.Type_Id,b.ParentId,b.Type_Name  from  tab a,--子节点数据集  Sys_ParamType_V2_0 b  --父节点数据集 where a.ParentId=b.Type_Id  --子节点数据集.paren

数据库无限分级(分类表)

在数据库中我们经常会做这样一件事:创建了一个分类表,再创建一个子分类,有多少级我们就习惯创建多少张表. 这样不仅耗费大量时间而且还会在操作表的时候陷入混乱,这里我介绍一种办法:无限分级. 通过这种方式,我们仅需要创建一张表就能将不管多少级分类全部放入. 首先我们理清一下思想,在这张表中我们要有个编号(ID),和一个父编号(ParentID) 我们在放入数据的时候就可以用ParentID去区别这个ID属于那个分级,而且通过这个ParentID,我们就可以实现无限分级,就是使用这个ID不断作为Par

无限极分类查找所有子孙节点的改进算法

在以前,遇到无限极分类返回一个节点的所有子孙节点时,我都是用递归计算的,后来发现时间复杂度和空间复杂度都太高了,后来自己研究了一下改进了算法. 节点数据如下:键值对分别是自己对应父亲节点 <?php $tree=array( 1=>0, 2=>1, 3=>2, 4=>3, 5=>4, 6=>5, 7=>6, 8=>7, 9=>8, 10=>9, 11=>10, ); ?> 以往算法如下: <?php function ge

SQL 语句递归查询 With AS 查找所有子节点

create table #EnterPrise(  Department nvarchar(50),--部门名称  ParentDept nvarchar(50),--上级部门  DepartManage nvarchar(30)--部门经理) insert into #EnterPrise select '技术部','总经办','Tom'insert into #EnterPrise select '商务部','总经办','Jeffry'insert into #EnterPrise sel

MySql 利用函数 查询所有子节点

前提:mysql  函数  find_in_set(str,strlist), cast(value as type)   一.find_in_set(str,strlist):如果字符串str是在的strlist组成的N子串的字符串列表,返回值的范围为1到N.  如果str不在strlist或strlist为空字符串,则返回值为 0 .如任意一个参数为NULL,则返回值为 NULL. 这个函数在第一个参数包含一个逗号(',')时将无法正常运行.   ①find_in_set(str,strli

采用左右值编码实现无限分级树形结构(转)

无限分级树形结构是在系统开发中很常见的,如下图 在之前实现这样的菜单一直是使用传统的方法,看数据表结构就一目了然 parent_id记录其直接父节点,组合树形结构的关键字段:parent_list记录其所有父节点,便于查询某个节点下所有子节点(一般使用MySQL的FIND_IN_SET函数),相对冗余.对于这种结构生成树形的关键算法:根据parent_id组合一个父子(直接关系)节点映射表,即 2 => array(3, 4), 3 => array(5),然后递归优先遍历每个节点的子节点.如

PHP实现文本快速查找 - 二分查找

PHP实现文本快速查找 - 二分查找法 起因 先说说事情的起因,最近在分析数据时经常遇到一种场景,代码需要频繁的读某一张数据库的表,比如根据地区ID获取地区名称.根据网站分类ID获取分类名称.根据关键词ID获取关键词等.虽然以上需求都可以在原始建表时,通过冗余数据来解决.但仍有部分业务存的只是关联表的ID,数据分析时需要频繁的查表. 所读的表存在共同的特点 数据几乎不会变更 数据量适中,从一万到100多万,如果全加载到内存也不太合适. 纠结的地方 在做数据分析时,需要十分频繁的读这些表,每秒有可

转:SQL SERVER数据库中实现快速的数据提取和数据分页

探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的“红头文件”一表的部分数据结构: CREATE TABLE [dbo].[TGongwen] (    --TGongwen是红头文件表名 [Gid] [int] IDENTITY (1, 1) NOT NULL , --本表的id号,也是主键 [title] [varchar] (80) COLLATE Chinese_PRC_CI_AS NULL ,  --红头文件