背景
在WEB开发中,采用前后端分离,要求对用户数据权限进行控制:
1.上级组织可查看下级组织的数据,同级别不能相互查看;
2.可设置仅查看自己创建的数据;
在数据库结构设计时,通常将组织机构设计为树形结构,表结构“Id,Name,ParentId。。。”,
Id Name ParentId Level
1 总公司 0 1
2 分公司1 1 2
3 分公司2 1 2
4 部门A 2 3
5 部门B 3 3
6 部门C 2 3
这样设计表结构清晰明了,可添加多级组织架构。不过,获得某人所在层级和所有下级列表时,SQL使用递归等方法效率较低,通常的做法是:
- 用户A已登陆,并携带token访问API,查询订单Order003
- API根据用户Id获得其所在组织及下级组织列表IdList
- 查询得知订单Order003是用户B创建的
- 获得B所以组织Id,并验证是否在IdList中
- 如果有权访问,则返回Order003订单数据,否则返回“无权查看”信息
以上步骤在SQL查询语句中虽然可通过多表JION及WHERE条件来实现,但运行效率很低,关键是这种权限验证非常频繁,造成系统整体运行效率低下,需要找一个更高效的方法来实现。
方案一
- 指导思想是“以空间换时间”
- 组织机构表设计成非树形结构
- 组织代码为
BIGINT
类型,最多9级,每级代码由两位数字组成(10-99)- 订单表中增加一个字段:创建人组织代码
--用户A是【A大区E公司】的,组织代码为111400,查询订单Order003,SQL大致如下:
select * from OrderTable where id=\'Order003\' and num between 111400 and 111499
是否有权限查看该条数据通过num between 111400 and 111499
来控制,如果无权查看,则返回空,执行效率几乎与无鉴权时相同。
方案二
- 本方案是在【方案一】的基本上进行改造,降低程序代码实现难度
- 组织代码字段为
VARCHAR
类型,格式为xx.yy.zz.
- 组织层级数不限,只要代码字段设置足够大
--用户A是【A大区E公司】的,组织代码为1.1.,查询订单Order003,SQL大致如下:
select * from OrderTable where id=\'Order003\' and num like \'1.1.%\'
总结
以上方法仅为组织机构权限验证的高效方法,供大家参考,谁有更好的思路请留言赐教!