前言

最近在自己搭建一个管理后台,到了权限角色的时候,按常规涉及了以下几张表:

也是相当常见的模型了。
但是随机我发现一个不大不小的问题,当权限表/资源表稍微大一点的时候,角色关联权限tbl_role_permission 就会有大量数据

这才一个角色,很伤脑筋。于是我想到了上个项目中用到的二进制表示权限方法。

表设计

二话不说,看表

我们知道一个long类型,可以转为64位的二进制类型,也就是说,0L就是

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

如果把每一个位置bit_pos表示一个权限,除去最左边的符号位以外,可以表示63个权限或资源,也就是一条tbl_role_permission 关联记录就可以表示63中不同权限。

其实按正常系统来说,63中权限、资源是肯定不够的,这时候就用bit_group来区分,超过63则划入另一个group。

也就是通过group和bit_pos来确定一个权限。

那么tbl_role_permission 就会是这样:

只是可读性变差了一些,但是关联看起来更简洁了

角色权限的增删

现在角色和权限通过一个二进制来关联,那么怎么给一个角色添加权限和删除权限呢?

增加

使用二进制的位运算,比如 现在一个角色的权限是 bit_group是 0, bit_str是00001111,要加入一个 bit_group是 0,bit_pos是5的权限 (这里bit_pos是从0开始,为了符合程序的索引下标规则)

规则如下
原二进制位权限 | 要添加的权限二进制位
首先得到权限的bit_str: 用到位运算的左移运算

1 << bit_pos

1 << 5 = 00100000
再和00001111 进行或运算

 00100000
|   00001111 = 00101111

删除

删除权限也很简单,还是上面的00101111,如果要把刚刚的bit_group是 0,bit_pos是5的权限删掉

还是先拿到二进制位
1 << 5 = 00100000

然后
原二进制位权限 & (~ 要删除的权限二进制位)
也就是
00101111 & (~ 00100000)

~ 00100000 也就是 11011111
再进行与运算

 00101111
&   11011111 = 00001111

判断是否具有权限

为什么采用二进制来表示权限,还有一个便利就是可以简单的判断这个权限属不属于这个角色的权限集合

如果一个角色的权限集合是 00001111,判断bit_pos是2的是不是这个权限集合:
原二进制权限集合 & ( 要判断的权限二进制 ) == 要判断的权限二进制
1 << 2 = 00000100

boolean b = 00001111
&   00000100
==  00000100

很明显判断结果为true

合并权限

要合并两个权限,不用担心重复的问题了,直接与运算
原权限 | 新权限

查询sql

说了这么多,怎么连表查询角色对应的权限集合呢?
根据角色名查权限

SELECT
*
FROMtbl_role r
LEFT JOIN tbl_role_permission rp ON r.id = rp.role_id
LEFT JOIN tbl_permission p ON p.bit_group = rp.permission_bit_group
WHERE
CONV(rp.permission_bit_str,2,10) >> p.bit_pos & 1 = 1
and r.role_name = ?
;

这个where条件其实就是将bit_str的权限集合,比如00001111,右移bit_pos,和1进行与运算,其实还是判断bit_str在第bit_pos个索引位置是不是1,是则有这个索引位置的权限,否则没有

介绍两个mysql方法
conv():

CONV(N,from_base,to_base) 表示转换进制, N是列名或值, from_base是从什么进制,to_base是转到什么进制
CONV(rp.permission_bit_str,2,10) 就是从二进制的01串变成十进制的数

BIN():

BIN(N) ,N是列名或值,将该值从10进制转成二进制,但是前面的0会忽略

LPAD():

LPAD(N,len,s),N是列名或值,len是总长度,s是当N长度不够len时,使用s来填充左边补全长度

所以如果我们想得到某个十进制的二进制位,

根据权限名查询角色
其实差不多


SELECT
*
FROM
tbl_permission p
LEFT JOIN tbl_role_permission rp ON p.bit_group = rp.permission_bit_group
LEFT JOIN tbl_role r ON r.id = rp.role_id
WHERE
CONV(rp.permission_bit_str,2,10) >> p.bit_pos & 1 = 1
and p.`name` = ?

总结

总之用二进制来代表权限,一个明显的好处就是原本63条数据库记录都可以用一条记录代替。而且判断用户权限的时候,不用从几十上百条权限里,一个个遍历判断进行鉴权。只需要进行一个二进制位运算就可以了。直接位运算一般都是比平时的代码要高效的。
缺点,表查询更复杂了,原本直接关联表id查询就可以,现在需要进行各种转换和运算。而且这个设计在工作交接的时候,还得需要详细交代bit_group和bit_pos是什么,有什么用,代码上的可读性也受影响了,容易看懵

使用二进制位来控制权限,表设计相关推荐

  1. RBAC、控制权限设计、权限表设计 基于角色权限控制和基于资源权限控制的区别优劣

    RBAC.控制权限设计.权限表设计 基于角色权限控制和基于资源权限控制的区别优劣 一.介绍 二.基于角色的权限设计 三.基于资源的权限设计 四.主体.资源.权限关系图 主体.资源.权限相关的数据模型 ...

  2. Shrio之权限表设计

    一.经典5张表 ①用户表 ②角色表 ③用户-角色表 ④菜单表(权限表) ⑤角色菜单表(权限表) 二.权限表设计 1. 菜单表 -- 菜单 CREATE TABLE `sys_menu` (`menu_ ...

  3. 会员权限 表设计mysql_用户权限管理数据库设计

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...

  4. 会员权限 表设计mysql_求用户-权限数据库表设计方案

    前不久做的一个系统,用户-权限是这样设计的, 用户表: Id int primary key not null identity(1,1) 主键 UloginName varchar(20) not ...

  5. BRAC模型 权限表设计

    在BRAC模型中,涉及到的关键元素有: 用户:系统的使用用户 角色 :拥有相同的权限用户 权限:系统可以被用户操作的元素(如:菜单,超链接) 以上元素的关系: 用户和角色是多对多的关系; 角色和权限是 ...

  6. 部门人员职位权限表设计

     用户角色多对多  角色权限多对多 用户部门多对多 部门表 用户_部门表 用户表 用户_角色表 角色表     角色_权限表 权限表 用户      用户_角色   (角色)      角色_菜单 ...

  7. 常用5张权限表设计讲解

    大致用到5张表:用户表(UserInfo).角色表(RoleInfo).菜单表(MenuInfo).用户角色表(UserRole).角色菜单表(RoleMenu). 各表的大体表结构如下: 1.用户表 ...

  8. 权限管理设计之菜单权限

     权限菜单的显示 MVC框架:struts2 + spring + hibernate 实现功能:后台管理系统中,每个登录的用户,有多个不同的角色,而每个角色都有不同的权限,针对每个用户所拥有的权限列 ...

  9. 3YAdmin-专注通用权限控制与表单的后台管理系统模板

    3YAdmin基于React+Antd构建.GitHub搜索React+Antd+Admin出来的结果没有上百也有几十个,为什么还要写这个东西呢? 一个后台管理系统的核心我认为应该是权限控制,表单以及 ...

最新文章

  1. AndroidStudio的几种依赖方式
  2. Vista下将目录的所有者恢复为 TrustedInstaller 的方法
  3. python国产_Python勒索软件来袭,国产杀软集体失身
  4. mysql增量同步kafka_MySQL数据实时增量同步到Kafka - Flume
  5. 【从零开始】Python字符串的操作方法
  6. Docker中RocketMQ的安装与使用
  7. 改进初学者的PID-手自动切换
  8. GlusterFS-Kubernetes云原生存储
  9. Linux统计目录下文件个数及代码行数
  10. 消息队列(MQ):ZeroMQ基本原理
  11. 计算机网络基本原理pdf,自考计算机网络基本原理课程学习指引.pdf
  12. Windows系统密码破解全攻略(hash破解)
  13. 现代软件工程讲义 4 方法论 - MSF
  14. PS 一键生成Android各个尺寸的图标
  15. 物联卡中心:物联卡是正规卡吗?与流量卡有什么区别?
  16. 计算机网络基础选择题
  17. bilinear 神经网络_基于多尺度双线性卷积神经网络的多角度下车型精细识别
  18. backtrader最大的坑:没有内置处理涨跌停板
  19. 云服务器2核和4核区别大吗?如何选择几核云服务器?
  20. oracle字符串转换浮点数,c#中将字符串转换成带2位小数的浮点数

热门文章

  1. 在.net Core 使用PDF模板文件生成PDF文件,代替WEB打印控件!
  2. Python学习记录(一)成绩转换
  3. 51单片机auxr寄存器_MCS-51单片机特殊功能寄存器详解
  4. html前端好玩小应用
  5. 虹科案例 | 2016年 Komatsu 138US负载下发动机抖动
  6. android8.0自适应图标,微软发布Edge浏览器最新版:支持安卓8.0自适应图标
  7. 政务大数据的本质是什么,包含哪些建设内容?
  8. Rust dependencies依赖管理crates.io原理梳理
  9. 递归算法的空间复杂度
  10. Java 检查内存溢出方法