通常树形结构的存储,是在子节点上存储父节点的编号来确定各节点的父子关系,例如这样的组织结构:
与之对应的表数据(department):
部门表结构(department)
id 部门编号
name 部门名称
level 所在树层级
parent_id 上级部门编号
1、问题来了
这样的方式很不错,可以很直观的体现各个节点之间的关系,通常可以满足大多数需求。但是当业务需求变得多了,数据量庞大了,这样的方式就不再适合用于生产。
例如:PM加了以下需求:
-
查出指定部门下所有子孙部门。
-
查询子孙部门总数。
-
判断节点是否叶子节点。
查出所有子孙部门
使用指定部门编号,一层一层使用递归往下查,可能是多数人会想到的方法。尽管在mysql8.0支持了cte(公共表表达式),递归效率比传统递归方式有明显提升,但是查询效率仍会随着部门树层级深度的提高而变差。
另外一种方法,一次性查出所有数据,放入内存中处理(数据量少时,可以选用。数据量多,不怕挨打的人也可以选这种)~
查询子孙部门总数
递归查询每一层的数量,最后相加。
判断是否叶子节点
-
方法1:可以加字段isLeaf的方式,来表示这个节点是否是叶子节点。
-
方法2:直接通过查询parent_id=当前id的count是否大于0,大于0表示不是叶子节点,等于0表示为叶子节点。
在日常中,可能会经常使用上述类似方法去解决类似的问题,但我觉得这样的方法在效率上不是最优解。于是乎开始查找更好的方案去解决这些问题。
要不试试这个方法?
直到后面查到国外一博客中,见到了所谓的《改进后的先序树遍历》文章(天哪,竟然是一篇2003年