背景
有这样的一个需求,比如是用户与角色的关系,两者是多对多的。一个用户可以有多个角色,一个角色包含多个用户。我们很容易就考虑到了RBAC权限模型,那创建一个用户表,一个角色表,还有一个用户角色关联表。多容易理解,多轻松啊。可是,如果角色不支持新建呢?固定只能是管理员、普通用户、只读用户。那你怎么做?还创建一个角色表吗?还创建一个用户角色关联表吗?当然,那肯定是可以的。不过角色表里面就永远只有3条数据,你每次查库的时候还总要join两个表,麻烦哦。那么,有没有一个不用新建表,又能维护用户和角色之间的多对多关系呢?答案就是位掩码。
原理分析
位掩码是一种使用二进制位来表示和存储多个开关状态或选项的技术。在您的设计中,每个平台的权值都被赋予了不同的2的幂次方值(20、21、2^2 等),这是位掩码的常见用法。
通过将平台的权值设置为2的幂次方值,并使用按位或运算将这些权值组合在一起,您可以有效地表示多个平台的选中状态,并将其存储为一个整数字段。而使用按位与运算,您可以快速检查某个平台是否被选中。
位掩码在计算机科学和数据库设计中有广泛的应用,特别是在需要对多个开关或选项进行组合表示和处理时。它是一种节省存储空间和提高效率的技术,也提供了一种简洁的方式来表示和处理多个状态或选项。
当使用位掩码时,我们将多个开关状态或选项用二进制位表示,每个开关对应一个二进制位,通常是0或1。通过将不同开关的二进制位组合在一起,我们可以用一个整数(通常是一个二进制数)来表示多个开关状态的组合。
假设有以下四个开关(参数):
参数1:权值为 2^0 = 1
参数2:权值为 2^1 = 2
参数3:权值为 2^2 = 4
参数4:权值为 2^3 = 8
现在,我们可以将这四个参数的二进制位组合在一起形成一个四位二进制数,例如:
0101 表示参数1和参数3被选中(1+0+4+0=5)
1010 表示参数2和参数4被选中(0+2+0+8=10)
1111 表示所有参数都被选中(1+2+4+8=15)
在数据库或代码中,我们可以使用这个整数二进制数(位掩码)来表示这四个参数的组合状态。然后,我们可以使用位运算来处理和查询这些参数。
通过按位与(bitwise AND)运算,我们可以检查特定参数是否被选中。
通过按位或(bitwise OR)运算,我们可以将参数的状态进行合并。
通过按位异或(bitwise XOR)运算,我们可以进行参数的状态切换。
使用位掩码的好处是可以有效地表示多个开关状态,并将它们组合为一个整数,节省了存储空间。同时,通过位运算,我们可以对这些开关状态进行快速的逻辑操作和查询。然而,也需要小心处理位掩码可能导致的溢出和位数问题。
解决问题
我们用位掩码来解决这个角色的信息存储。这个案例不太有现实的意义。。仅供参考,切勿深究。用户表中新增一列auth,用于保存位掩码。
约定:
管理员:1
普通用户:2
只读用户:4
如果勾选了 管理员 和 普通用户,保存的结果值为3( 1 + 2 = 3),同理可配对任意的组合,每种组合的和值都会是唯一的。
在检索是否勾选了管理员角色,即可通过如下语句:
select * from user_info where bitand(auth, 1) = 1;