先简单看一下简单的表结构以及表关系。
表解释
- 用户相关
User
用于存储用户信息,主要字段为id
用户信息等
- 组织相关
Organization
用于存储组织架构中的单个组织,主要字段为id
,name
等等Relation
用于存储组织架构中的组织间关系,主要字段为parent_id
,child_id
- 群组相关
Group
用于存储群组信息,主要字段为id
群组名等Service
用于存储服务信息,主要字段为id
服务名称等Api
用于存储接口信息,主要字段为id
,url_name,
app_name`等- 另外还有两张表用于存储
Group
与Service
的多对多关系以及Service
与Api
的多对多关系
- 将上述关系组织到一起
UserPosition
记录一个人在哪些组织上属于什么群组,主要字段有user_id
,group_id
,org_id
概述
上述的那么多表,其实只是解决了一个问题『一个人在什么范围能做什么事情』。
- 一个人 即 用户相关的表
- 什么范围即 组织相关的表
- 什么事情 即 群组相关的表
用户相关
即权限系统中的用户,并无复杂概念
组织相关
现实生活中的组织架构是一个类似树形的不规则结构,如下图所示
如果是存储树形结构,第一反应可能是在每个节点记录一个 parent_id
。这是最简单的做法,但是在查询某个节点的所有子节点的时候却是效率最差的做法。
这里我们采用的方法是单独拿一张关系表记录父节点到所有子节点的数据。这样做的好处是查询效率非常高,只是在插入数据的时候稍微慢一点,但是考虑到我们的应用是读大于写,所以这样做并无不妥。按照上述说法,则可以用下表表示下图。
父节点 | 子节点 |
---|---|
root | mid_a |
root | bottom_a |
root | bottom_b |
root | bottom_d |
mid_a | bottom_a |
mid_a | bottom_b |
tip: 如果为了方便,可以为每个节点插入一条父节点和子节点均为自己的记录。
该方法并非独创,详细的分析该方法以及与其他方法的对比可参见https://www.slideshare.net/billkarwin/models-for-hierarchical-data
群组相关
在群组这部分的设计中,包含了五张表。但是关键的概念仅为 Api
, Service
, Group
, 其实这样设计会稍显复杂。那我们为什么要这样设计呢?
最重要的原因是将开发与产品/运营间有效的隔离开。
Api
表记录的是系统中所有的接口,这是开发需要维护的部分。
Service
表记录的是系统中的功能点,这是需要产品/运用同开发共同维护的部分
- 产品需要提供要在管理后台中功能点的管理粒度,比如说是:用户管理(包含用户查看,用户删除,用户修改等功能)还是用户查看?
- 开发则需要将 Api 中与产品定义好的 Service 关联起来。
Group
表记录的是系统中的群组,这是需要产品维护的部分,同时产品需要维护群组与功能点的关系。
ps: Api
表中的 app_name
与 url_name
是为了保证在不同系统中相同的 url
可能会冲突的情况
pss: 🤔仔细想想,Api 表中的 api
是不是可以偷懒的整个一个系统只用同一个呢?甭管你有多少接口,全部一把梭,都用同一个 api
。当然可以了,只要能满足需求, api
怎么记录完全看你自己,这也是本系统灵活的原因。
n more thing
- 是不是可以将组织架构依赖公司内部的 hr 系统?这样公司组织架构变动的时候就不用手动维护了。
- 是不是可以将用户表也通过对接公司内部的 hr 系统来完成呢?比如对接一个 oauth,这样这个人离职/入职也不用维护这部分内容了。
- 用户岗位部分是不是可以通过上一步介入的 oauth 拿到用户的岗位信息?通过一个员工岗位与系统内群组的对应关系的表,是不是就可以自动的让用户登录后拥有相应权限了?
- 用户岗位部分是不是可以支持手动添加岗位?只要通过添加一个字段表示这个岗位是自动同步的还是手动加入的,自动同步的每次登录的时候刷新,非自动同步的只能手动修改。这样谁谁谁要临时加一个权限,也不用头疼了。