今天给大家分享一下,橙单中规避了递归查询的部门树的实现方式。
这个是需要结合昨天分享的数据权限,一起去看的。
橙单微服务的权限部分之过滤规则
昨天我们介绍过,数据权限,几乎贯穿80%的sql,所以优化极为值得。
在橙单中,有基于部门的数据过滤权限
实现一下这个权限,本部门及其子部门,试想一下
如果有三个部门层级,就有了递归,如果每一条涉及数据权限的sql,都会被绑定一个递归条件,这几乎是不可用的。
有多种实现方式,集中最简单的就是,每个部门,都有一个parentid字段,然后过滤的时候,不停的递归
这个方式是不可取的
还有一种就是部门表中有个部门路径字段,
比如 / dept-a / dept-aa / dept - aaa
这样如果查询dept-aa的子部门的时候
就是 dept_path like ‘%/dept-aa%’
这个实现方式没有递归,但是有两个弊端
一个是like ‘%’ 开头的时候,直接抑制了索引
性能也是不高的,高频的操作,会导致数据库读锁过于频繁,有的甚至会影响写入的效率,毕竟没有索引的查询,就是全表扫描了
单位查询时间长,数据库锁持有和等待的时间也会增长
还有一个弊端,就是 用户层级变化的时候,比如 /dept-a / dept-aa / dept -aaa,改到 /dept-b/ dept-bb/dept-aa/ dept-aaa
这种层级的变化,尽管比较低频,但是代码都特别不好写,
而且全表扫描的排它锁,
很容易导致死锁的产生
橙单使用了几乎是最优的实践方式,如果你有更好的方法,可以评论留言
这个是橙单官档的例子,也详细解释了这个技术点
因为这个确实是非常值得橙单吹一波的实现方式了
橙单做的是,将树形数据,扁平化,典型的空间换时间。
扁平化之后就是这样的
这个就是橙单自动补偿的数据过滤条件
可以看到,橙单一步就查询出了所有的部门及其子节点
而且所有的条件都有索引支持,甚至是全索引查询。
因为就会非常高效。
在查询多个部门及其子部门的时候,只是将 等于,改为了 in list
不仅代码可读性高,而且性能超高。
修改部门数据的时候,也仅仅当部门parentId变化的时候才会同步更新部门的层级关系。
当出现部门parentId变更的时候,我们先删除当前部门和之前父部门的关联关系。这个操作也是批量完成的,而且每一步操作都有索引支持,甚至是主键支持
再将当前部门和新的父部门建立关联关系
让当前部门的子部门,和新的父部门重新建立关系
最后一步批量插入,特别是在数据量大的时候,批量插入很有价值
在批量插入父子关系的时候,橙单采用了非常高效的闭包方式。有兴趣大家可以看一下
好了,今天分享到这里,希望对橙单代码有兴趣,且热爱技术的开发者,可以得到更多收益。
问:
这存储是不是有歧义 父节点是自己节点
答:
这个是必须的,要想一次出数,这个是必须的
这个本身就是无限层级父子关系数据的极致优化
性能提升n倍以上