利用位运算处理权限分配来优化数据库存储,并且提高运算效率
程序员文章站
2024-01-25 21:32:10
...
这个是临阵磨枪的,在现在做的一个OA项目中,由于多权限造成后台静态管理网页泛滥了,现在不得不改进些新的技术,又因为以前的权限表是作为管理员表的外键,给这次修改带来很*烦,所以想到了类与Linux的位运算权限管理方法。 其实微软的API参数很多也是使
这个是临阵磨枪的,在现在做的一个OA项目中,由于多权限造成后台静态管理网页泛滥了,现在不得不改进些新的技术,又因为以前的权限表是作为管理员表的外键,给这次修改带来很*烦,所以想到了类似与Linux的位运算权限管理方法。其实微软的API参数很多也是使用宏定义好的,然后才可以进行或运算的传参,如一个MessageBox 的参数大致可是这样的,有一个按钮|有提示图标|有提示文字 等等,这样的或运算得到的结果就是功能都包含的结果.
先以Linux的read-1,write-2,executable-4来句例子,大家耍过linux的都知道,ls -l 这个指令就可以显示出linux的详细权限,说一下这样1读2写4执行的原理,因为这里也利用了数学的一点小知识:
一个byte=8bit,可以表示的范围是0-2^8-1,这一个byte的值如果是0,表示没有任何权限,如果是1表示只有读的权限,如果是2表示只有写的权限,如果是3表示有读写权限,以此类推。
这是Linux 的权限管理原理三位表(实际Linux这部分的权限管理只用了三位,不是一个Byte):
这样设计的好处是啥吗?
首先,这样设计节约空间,在硬盘或者文件开辟较小的空间,然后就是位运算在CPU执行起来效率比普通运算要快的多,直接电位变化,很快得出运算结果。
然后就的分析真正的算法实现了
我这里的权限一共有8个之多,我首先要做的就是取消原来的权限表的外键关系,因为外键这是一对多的关系,在这里已经不再适用,并且如果我简单的在管理员表中添加几个字段来表示多权限,那样看起来有些冗余,所以这里的权限字段还是维持一个字段不变,然后根据不同的值确定他具体具备哪些权限。
具体设计如下:
1-提案权限(2^0)
2-学院初审权限(2^1)
4-学校初审权限(2^2)
8-学校复审权限(2^3)
16-学校终审权限(2^4)
32-网站管理员权限(2^5)
64-相关部门权限(2^6)
128-牵头办理部门权限(2^7)
你可以当我是在假设这些权限,没必要具体理解他,如果是上面这几个权限,只需要一个Byte就够了(八位)
最初的权限默认是1,就是只有提案权限,然后就是重头戏,权限的动态管理:
增加权限:如给他学院初审权限只需要在原来权限或运算2就是行了(原来权限"2)
增加多个权限:原来权限|2|4|8 ,这个值就同时具有了学院,学校初审,学校复审的权限。
删除某个权限:只要让原来权与非一个权限就是OK(原来权限^2,就是删除了2的权限)
删除多个权限:只要原来权限同时与非多个权限就是OK了(原来权限&~2&~4,就是删除原来权限中的2,4权限)
分离出具要的权限:只要让权限集与2的指数,等于某权限项的就是拥有的权限
for i in range(64):
if privilege & 2**i == 2**i:
privilegelist.append(i)
简单的是现实就是加权限就是采用加法,减权限就是采用减法,但是这里的直接采用加减并不提倡,原因是1.加减法效率低,2.加减法容易溢出,比如减的权限权限本来就是不存在的权限,就会报错
注意的问题:
1.在mysql等,其中bigint 就是8字节,最多可以设置八个权限的组合(8×8-1种权限)
2.int 就只能设置4种权限共8x4-1种权限组合
最后说点前台修改数据然后后台修改权限的思路:
简单的几个checkBox 代表不同的权限,注意这里的CheckBox也是按照原有的权限范围循环出来的,
比如权限范围是2^0 ~ 2^7 其实就似乎对应0,1,2,4,8,16,32,64,128这几个数,然后到权限表中查到这几个数对应的中文名字在checkBox中打印出来,更新的时候根据每一的值进行循环或,这样权限集就是修改后的结果了,呵呵
这样后台权限页面的控制也瞬间变得简单了,直接几个大的模板页面就是OK了,当然这时候的模板页面就要设计的复杂一些,每个功能标签都是根据有无权限项循环打印出来的
这种按照位运算区分权限的思路是通用的,并且这里从数据库设计到前台实现都扯了一遍,希望您能有点收获。
下一篇: php长字符串定义方法_PHP