最近做一个项目,有一个权限管理模块。 因为数据库用的是 MYSQL,所以本人建议基于 RBAC 做一个功能比较完善的权限管理系统以绝后患。 这个系统最基础结构就是 User-Role-Permission 中间用关系表连接的 5 表结构,不管是权限管理还是特权管理感觉都是很好很流行的方案。 结果公司里人说表太多了,把 permission 表去掉然后把特权用 JSON 数组连接放进 Role 表里这样就能省 2 个表了。
我就不理解了,现在的人是 nosql 用太多了还是怎么了,整天想着把数据放进 JSON 字段里,那还用关系型数据库干什么呢?
哪位大佬帮我分析分析利弊。
1
jedrek 2019-07-01 13:38:52 +08:00
“结果公司里人说表太多了,把 permission 表去掉然后把特权用 JSON 数组连接放进 Role 表里这样就能省 2 个表了”
——————— 这样有何不好呢? |
2
rogwan 2019-07-01 13:40:06 +08:00 via Android
用到事务和多表联合查询,关系型数据库的优势就体系出来的,“关系”这两个字已经自己表态了。
|
3
chendy 2019-07-01 13:40:10 +08:00
如果用的是支持 json 字段的 mysql 还可以考虑
否则为了”省几张表“而做这种事情都是给自己挖坑 |
4
dajj 2019-07-01 13:40:32 +08:00
其实吧。。。也行 。 谁设计以后需求变更了谁来改。
|
5
buxudashi 2019-07-01 13:41:25 +08:00
公司里的人,比较聪明的一个。一下就找到了优化方法。
省也只是省一个表吧。 |
6
loading 2019-07-01 13:43:17 +08:00
mysql 存 json 吗?我只有魔改第三方系统的时候用过几次。
|
7
zidian9 2019-07-01 13:43:57 +08:00
数据库表数据一大,根本不敢用关系型数据库的特性 [锁表,连表查]
要不是非关系型数据库的可靠性还不够,管理起来不够方便,早就用非关系型数据库了 |
8
HuHui 2019-07-01 13:44:03 +08:00
今天省下的用明天来补上
|
9
Hanggi OP @jedrek 现在所有权限都在 JSON 里,接下来你要给一个 Role 添加新的特权你要怎么做?手动填写并加进 JSON 数组里吗?
如果需要列出现在所有的特权,你要怎么做?遍历整个 Role 表里的 JSON 然后合并,再列出来吗? 如果需要找出对项目 1 有改权限的所有 Role 甚至是用户你要怎么做?再遍历一遍 Role 表从那么多的 JSON 数组里找指定字符串并且寻找对应的用户吗? 请解释下怎么实现? |
10
est 2019-07-01 13:50:40 +08:00
我比较好奇为什么 RBAC 需要 5 个表。。。
|
11
est 2019-07-01 13:51:35 +08:00
@Hanggi mysql 可以做 generated column,pg 可以做 function index。不存在遍历 role 表的 json 的问题。现在 db 溜得很。json 可以放心用。
|
12
zidian9 2019-07-01 13:52:30 +08:00 2
放 JSON 可不是那么方便
比如,2 个线程同时更新这个 JSON, 进程 1 读取 JSON 进程 2 读取 JSON 进程 1 添加权限 A 进程 2 添加权限 B 进程 1 写 JSON 到 DB 进程 2 写 JSON 到 DB 那么最终 JSON 里面只有权限 B,还得给它加个乐观锁 |
13
cherryas 2019-07-01 13:52:43 +08:00
负责人是前端出身?
|
14
LudwigWS 2019-07-01 13:53:30 +08:00
感觉数据库表设计还是比较高端的技术。
|
15
Hanggi OP @est 用户表( User ),角色表( Role ),特权表( Permission ),然后是用户角色关系表和角色特权关系表。比较完整的结构?有更好的实现吗?可以支持交叉授权。
|
17
laojiaqing 2019-07-01 13:58:08 +08:00
其实我也一直在思考这个问题
|
18
xkeyideal 2019-07-01 13:58:24 +08:00
使用什么数据库根据需求和开发人员技术熟练度,加上公司运维条件来定。
nosql === json,这个表述有问题,楼主的理解也有问题,mongodb 的 bson 结构也能支持复杂的查询。 再说说权限管理,RBAC 真的很过时,只能解决路由的权限问题,数据的归属权限无法解决,随着需求的迭代,暴露的问题会越来越多 |
19
limuyan44 2019-07-01 13:58:51 +08:00 via Android 2
你不理解,为什么不当面问问公司里说的那个人呢。。
|
20
TobiahShaw 2019-07-01 13:59:32 +08:00
这个违反了一范式吧,数据失去了结构性
|
21
maichael 2019-07-01 14:00:25 +08:00
除非是底层支持 json,不然这种用单个 json 代替的后续维护都很麻烦。
|
26
Lucups 2019-07-01 14:04:55 +08:00
楼主没有说什么量级项目。
我觉得还是要先看是项目的大小,然后再判断合不合理。如果只是一个简单的小项目那就无所谓了,怎么快怎么来。 话说,现在的人还在自己写权限模块?主流的框架都有成熟的权限模块了吧... |
27
12tall 2019-07-01 14:06:02 +08:00
@est 请教大神。目前设计的用的是 sqlserver 用了 8 个表:用户,角色,科室(闭包表),权限,再加上中间表。确实感觉表比较多 但是想不到更好的办法了~~~
|
28
Hanggi OP @Lucups 项目不算小项目,但是因为是 2B 的所以用户量可能不会很大。但是项目复杂性是有的。
主要权限不是单纯的路由权限,还有指定资源衍生出来的各种服务的权限。如果只是单纯路由权限可能不需要这样。 |
29
jadec0der 2019-07-01 14:08:48 +08:00
对,现在 RDB 在互联网公司的主流用法就是不用外键。至于 NoSQL,有 DynamoDB 用还可以,Mongo 靠不住啊
|
30
zhouyou457 2019-07-01 14:13:50 +08:00
万一特权要更新或者删除怎么办?把所有角色遍历一遍?
|
31
Hanggi OP @zhouyou457 关系表是干嘛的,如果你要把特权 id=100 的特权删掉,只要在关系表里把 permissionId=100 的关系全删掉不就行了吗?还有一种方法就是在特权加一个状态,表示这个特权废弃了。
|
32
xkeyideal 2019-07-01 14:17:59 +08:00
@Hanggi
@chendy https://blog.csdn.net/Acceptedxukai/article/details/78297879 在 RABC 基础上进行了一种数据权限实现的封装 |
33
securityCoding 2019-07-01 14:18:00 +08:00
省他妹 ,这么简单清晰的东西非要按照自己的野路子思路瞎改
|
34
mooncakejs 2019-07-01 14:21:04 +08:00 via iPhone
实际开发中有一些对象没有单独查询的需求,只是另一个对象的附属。就适合用 Json 字段。
|
35
libook 2019-07-01 14:22:01 +08:00
数据模型大部分为关系模型就用关系型数据库,数据模型大部分为文档型就用文档型数据库,现在大型业务都不是在一个服务上独立做的,涉及到事务也是平台级别的事务,所以按照数据操作的最小粒度来将不同模式的数据模型拆开,可能是比较好的方式。
像学校、老师、班级、学生这种模型就是典型的关系模型,最好使用关系型数据库;学生学习记录会包含学生、课程等当时的状态快照,所以适合使用文档型数据库;然后在平台级别学生和学生学习记录之间又是关系模型。 又比如正常的业务逻辑使用常用的关系型数据库,涉及到搜索的部分用特殊的数据库(数据存储、搜索引擎方案) Elasticsearch。有的公司是同一份数据同时存在多种数据库里,增加了保障一致性的复杂度,获得了最佳综合性能。 |
36
ttentau1 2019-07-01 14:24:23 +08:00
@cherryas 这和是不是前端出身没有关系,经验问题吧。我前端用过 node+mongodb 之后毅然决然转 php+mysql 了。json 只适合存储不需要变动的数据,比如日志文件,历史记录之类的。如果频繁修改的数据还用 json 来搞,这个人绝对不专业
|
37
est 2019-07-01 14:24:42 +08:00
@Hanggi 好吧。这样看起来的确需要 5 个表。如果用 JSON 的话中间表的确是可以直接放进 permission role 表的。
|
38
version 2019-07-01 14:35:46 +08:00 2
看企业需求吧.
rbac 其实不适合魔改的国内企业内部架构.很多还要加一个组织的模块. rbac 给国内企业使用就是每个人一个角色.每个人 n 个 div 角色.维护起来很累的.特别是上级权限更新的时候 然后权限基本是有些是跨部门的. 特别是相关联的其它业务需要下发通知什么的.和数据权限.. 如果是自家百来人企业..如果人数不多. 推荐还是 user 对象放一个 role 存 json 然后前端配置可以多选的权限级.这样每个人单纯的权限管理.前端只做适配和可视化整理.页面有角色组.而实际数据库没有角色组. 权限管理对于后台来说是很重要的.对于数据权限也重要.最好根据其它业务来适配最好了. 标准不一定适合企业自己.程序也是.合理不留坑是最好的了. |
39
niubee1 2019-07-01 14:44:41 +08:00 1
你的权限规模有多大啊?几万条记录?十几万条记录?大内存数据库实例里几万条记录不加索引跑得还更快一点,再反过来看看, 要是就这点量的话,存 json 文件启动的时候加载到内存里也毫不维和啊。
上来就先拉关系排几个表开撸的一般都菜, 你做事前先分析下需求先, 确定下规模, 不同规模有不同的玩法。你要说规模庞大你还可以上 LDAP 啊,KeyStone 啊 |
40
zjsxwc 2019-07-01 14:59:49 +08:00 via Android 1
说实话如果没有上千个 role 需求的话,
把 role 与 permission 都硬编码写到一个 json 文件里就可以了, 要修改或者增加 role 与 permission 的话,直接代码里改下就好了。 |
42
charlie21 2019-07-01 15:23:34 +08:00
@securityCoding 我也觉得这个有现成的解决方案吧,非瞎改什么呢
|
43
zjsxwc 2019-07-01 15:25:05 +08:00 via Android
|
45
Aresxue 2019-07-01 15:34:55 +08:00
这表还多。。。看样子项目没太大的用户量吧,那目前这么做也没啥问题,然后祈祷项目死掉,千万别大规模商用。。。
|
47
Hanggi OP |
48
vus520 2019-07-01 15:41:47 +08:00
为了表的数量把问题复杂化的,都是一群没被自己坑过的坑货。
|
49
passerbytiny 2019-07-01 15:55:09 +08:00
兄弟,你有没有想过,你弄个完整的 RBAC,人家看得懂吗?人家要的不是省下两个表的空间,而是两个表的(面向外行人的)理解难度。
|
50
smallpython 2019-07-01 16:20:25 +08:00 1
可以想象当初琢磨着发明 nosql 的人们就是在这样的困惑下开始的,但是只要你的思维不局限于,sql 和 nosql 一定存在一个比另外一个好,另外一个必将被历史淘汰的思维定式里,你就会发现没什么好纠结的.
无论什么技术都是为功能服务的,技术本身不应被信奉 |
51
husinhu 2019-07-01 16:41:49 +08:00 via iPhone
Mysql 的 proxy user 了解一下
|
52
husinhu 2019-07-01 16:47:50 +08:00 via iPhone
proxy user
|
53
Felldeadbird 2019-07-01 16:48:52 +08:00
虽然 MYSQL 已经支持 JSON 操作了,所以这样设计没毛病。
只是我个人觉得,在存储 JSON 时,需要考虑好日后统计数据用。 不过既然是权限管理,一般不涉及这样的统计,主要考虑是今后的权限细分,例如,帐号保护子账户的权限………这时候用 json 去保存,估计结构复杂上来了。 最后就是,不要过度设计就行了。未来的事情未来再说吧,。 |
55
akira 2019-07-01 16:59:14 +08:00
你的疑问没错,所以确实 nosql 发展起来了
|
56
q4336431 2019-07-01 17:00:00 +08:00
个人认为,无论用哪种方式,都先罗列出利弊,然后讨论取舍,选择利大于弊的方案,如果双方都不赞同对方,那么就让上面决定。
|
57
reus 2019-07-01 17:09:27 +08:00 1
如果不是 mysql 8,本身有 json 字段类型的话,这样做就是蠢
就算支持 json 字段,不支持索引 json 内部数据,也是百搭 如果要删除某个 permission,要遍历所有 role ? 检查 permission 时,也遍历所有 role ? role 少可能还没啥大影响,role 一多,或者设计成默认一个用户一个 role,我看你怎么死 这个就是所谓提前优化,多鸠余 |
58
ziding 2019-07-01 17:14:19 +08:00
典型的过早优化
|
60
arthas2234 2019-07-01 17:24:25 +08:00
要对 permission 进行修改怕是要给整哭了,如果对 mysql 有版本要求,怕是要挨打
对于权限这一块,关系很清晰了,建立好索引都不是事 这种复用性强的功能就应该封装一个兼容性好的库,一劳永逸 |
61
Yourshell 2019-07-01 17:25:57 +08:00
三个表就嫌多吗
|
62
Defned 2019-07-01 17:29:26 +08:00
casbin 了解一下,一张表搞定,当然也可以不用表
|
63
lonelygo 2019-07-01 17:36:17 +08:00
用户权限,这么有“关系”的事情用“关系库”挺好啊。
表不怕多,怕不可理 |
64
A555 2019-07-01 17:37:31 +08:00
整天搞这种骚操作给后面的人埋坑
|
65
cccy0 2019-07-01 18:08:31 +08:00
看业务把, 毕竟关系型还是有优势的
|
66
zhixuanziben 2019-07-01 18:24:09 +08:00
感觉这是在挖坑啊,那么经典的 rbac 模型,5 张表。为了省表,到时候拓展起来就要哭了。
|
67
awesomes 2019-07-01 18:29:14 +08:00
实际上,可以用一个 JSON 把所有表的数据都搞定,你说呢
|
68
swulling 2019-07-01 18:37:18 +08:00 via iPhone
你的做法是对的,这种需求用 sql 最合适了
|
69
hsluoyz 2019-07-01 19:06:04 +08:00
+1,直接用 Casbin 吧,简单、灵活,把精力省下来用在其他地方,没必要重复造轮子
|
70
DaWWW 2019-07-01 20:03:06 +08:00
这个单看楼主的描述,其实怎么实现都没问题,但应用场景和规模会决定用什么更好,不能一概而论,并没有单纯的好或者不好。我觉得楼主如果有针对实际需求的完整的方案,还是可以据理力争的。有件事情,真的真的非常重要,软件项目的成功,依靠的是社交,而非技术。
|
71
leegoo 2019-07-01 21:14:10 +08:00
RBAC 的话 数据量应该不会很大吧,毕竟是针对后台管理的
关系型数据库挺好的啊,为啥一定要上 NoSql 而且 RBAC 更多的是与业务权限进行关联,肯定多表查询的几率会很大, 而 NoSQL 对于多表查询并不友好吧(虽然可以使用多次单表操作) 况且,省了几个表 后期维护的成本变高了很多,表和表之间的关系也耦合在一起了,后期想要扩展想必肯定是一件很头疼的事情吧 再说了 |
72
soulmine 2019-07-01 21:25:11 +08:00
你的观点是以绝后患 那么存在这个后患么?后患的几率多少 有必要用 5 个表么? 2 个表行不行 能不能完成? 不是所有东西都是越复杂越好的 得看实际需求
|
73
kyuuseiryuu 2019-07-01 21:32:10 +08:00
因为所谓的业务系统就是把现实中的对象的属性、行为以及对象与对象之间的关系用计算机语言描述出来。
所以注重“关系”的业务一般都采用关系型数据库。 |
74
xuanbg 2019-07-01 21:38:24 +08:00
@xkeyideal 数据权限不好实现的根本原因是数据资源难以定义。在你的权限体系里面,signKey 其实就是数据资源。但我没看明白你这个 signKey 是如何产生的,这个关键点能详细说一下吗?
|
75
xuanbg 2019-07-01 21:42:48 +08:00 1
@Lucups 主流框架集成的不是用户身份认证吗?就算是身份认证,也是只有最简单的功能。我还不知道哪个主流框架集成了权限管理,也想不明白权限管理这种严重依赖数据库的功能要怎么集成在框架里面。
|
76
cabing 2019-07-01 22:35:33 +08:00
如果没啥量,需要考虑可维护性。
数据库字段里面存 json,除非是一次性存取的,不然很危险,维护起来超级麻烦,如果后续有变更啥的或者是开发随意定字段啥的,你们维护起来会哭的。真的,别问我为什么知道。。 |
77
springmarker 2019-07-01 23:23:32 +08:00 via Android
很多业务其实单表就够了,像 mongo 这种连表查询能烦死个人,但是照样很多人用
|
78
turandothaha 2019-07-02 07:13:16 +08:00
不看书就没有发言权,不知道从哪里看到现在可以不用关系型数据库的?
没看见有可替代的东西,也没看见要式微的迹象啊,nosql 能替代关系型数据库? 还是先找本书看看吧。 |
79
Salvation 2019-07-02 07:40:31 +08:00
。。。。。。。。。
感觉都没有人说到非常重要的一点,表结构这些玩意的最优方案,都是从领域模型+业务场景推导出来的。不是一上来就看 db 应该怎么设计。 单单要说怎么存储,那怎么存储都可以,用不着纠结,关键是能不能说清楚核心原因。 |
80
nl101531 2019-07-02 08:57:12 +08:00
没理解多两张表的复杂性在哪,多的两张也只是权限配置表,那么在组装用户 domain 的时候,对上层是屏蔽了这些东西,没有带来太多复杂性吧。
|
81
IamNotShady 2019-07-02 09:18:50 +08:00
如果权限配置不经常变更,这样设计也没问题,但是如果角色的权限经常变动,或者系统增加新的权限,这样搞就有点坑了
|
82
encro 2019-07-02 09:35:15 +08:00 1
2 张表也能做 rbac 而且可以多级继承:item(id,type,name),assignment(id,type,from_id,to_id),前提是定义好两个 type。
以上实际项目中最好不要用,因为记住多张表会比记住 type 要容易得多,容易记住就等于出错概率少很多。 |
84
coang 2019-07-02 10:57:34 +08:00
......5 个表不是标配吗.. 生成权限 json 这种东西 写个方法缓存一下不就完了???? 删掉关联表存 json??? 本末倒置
|
85
coang 2019-07-02 11:00:50 +08:00
@xkeyideal 其实在功能表 加上对应的 url 然后在后端 配合 shiro 做认证 不仅仅路由权限可以卡 对应接口权限也可以做校验.. 只是有没有这个闲工夫去做..
|
86
lepig 2019-07-02 11:34:18 +08:00 1
为了省 2 张毫无数据量的表,而把数据放到 json 里。我可以明确告诉你,这就是个坑。
维护到后面你就知道了,各种权限更新,判断折磨的要死 |
87
wlkq 2019-07-02 11:36:56 +08:00
各有优缺点吧,优点:不用联查表,一次就出来了 缺点:角色之间的权限重复的话,需要重复写入,权限无法复用,这里有点坑。如果再频繁更改权限的话,更坑。
|
88
FrankHB 2019-07-02 11:57:26 +08:00
RDBMS 适合做且其它 DBMS 不适合做的,原则上主要就是连接查询。
(事务支持是实现问题,会影响选型,但不应该是原则问题。RDBMS 本身不蕴含事务支持,NoSQL 也有事务支持较完善的实现。) 所以首先应该有疑问的是:为什么一个系统业务逻辑上不需要依赖连接查询的时候,还要上关系数据库? ——历史包袱罢了。 不过你这里业务上也没必要彻底排除连接(彻底排除想保质保量估计 hold 不住),个别地方多用少用几个算不上是原则问题。 所以就是看人员素质了。要是那些人就是喜欢倒腾 JSON 还保证能应付掉所有需求变动那就随他们去吧,你能把锅甩干净就成…… |
89
dbpe 2019-07-02 12:12:03 +08:00
这几个字段管生不管养的话,没问题。。
|
90
FrankHB 2019-07-02 12:21:27 +08:00
@turandothaha 这跟看书有关系?
现在有啥书会告诉你 RBAC model 里的 relation 非得用 RDBMS 实现么。 我寻思 INCITS 359 也没钦定要 RDBMS 啊…… 极端点说拿个底层查询引擎再往上糊个什么 duty language 之类的备胎都可行。只是一般场景毫不现实罢了。 |
91
htxf 2019-07-02 12:22:22 +08:00 via Android
各位这样交流真好,不是太懂。。认真学习中。。
|
93
dakb 2019-07-02 12:57:57 +08:00
你的标题起的太挫了吧。
|
94
qiumaoyuan 2019-07-02 14:02:18 +08:00
省 2 个表的意义是?
|
95
qiumaoyuan 2019-07-02 14:02:54 +08:00
有时候开发者会为自己设置一些自己都不明白的规则来限制自己。
|
96
turandothaha 2019-07-02 16:23:36 +08:00
|
97
www5070504 2019-07-02 16:46:29 +08:00
节省一两张表好像看着挺机灵 改的时候绝对要司马脸
|
98
z1154505909 2019-07-02 16:48:16 +08:00
只有写查,没有改的数据存 json 无可厚非,会有改的,弄 json 就是搞事.
|
99
FrankHB 2019-07-02 18:19:55 +08:00
@turandothaha 才主张“不看书就没有发言权”,一忽儿就评价理论呆子了……似乎还觉得 01 就是理论,也是奇妙深刻 qqqxx
不过我寻思你的确呆子页算不上,因为……比如你连哪本书都没说……打搅了,告辞。 |
100
turandothaha 2019-07-02 19:33:06 +08:00
|