zoukankan      html  css  js  c++  java
  • (一)二进制位运算实现权限系统

    1.传统用户权限存储方式
    1>用户:rights:{“/hello.do”,“/hi.do”...}。
    2>用户:rights:{1,2,3..}。
    3>用户端不存储,每次去数据库查询比对。
    弊端:
    1>当权限链接成百上千的时候,用户的权限链接存储浪费一定的内存资源,而且,每次比对效率较低。
    2>若每次比对查询数据库,给数据库造成一定的压力影响程序的整体性能。
     
    2.二进制位运算权限控制
    优点:
    1>用户只需要存储权限总和long 或 long[](存储量极少)
    2>权限比对的时候只需要用权限码与用户的权限总和进行位运算即可(比对效率极高)
     
    实现原理及过程
    过程:
    1>权限表里面添加权限码字段rcode(java端Long 类型 mysql端 bigint类型)rcode的计算方式:从1开始 每次递增为 上一位的权限码向左移动一位(即 上一位权限码乘以2)
    2>用户的权限总和将用户所关联的权限集合中的每一条权限的权限码按照“或运算 |”的计算的果即为用户的权限的总和。
    3>权限比对将要访问的链接的权限的权限码与用户的权限总和进行“与运算”若结果不为0即表明用户有该权限。
     
    原理:
    若有权限码
    1 0001
    2 0010
    4 0100
    8 1000
     
    若用户有1,2,8三条权限,则用户的权限总和
    0001 | 0010 | 1000 =1011=11
    此时若操作权限码为2(0010)的权限权限总和
       1011
    & 0010
       0010 > 0 (有操作权限)
     
    此时若操作权限码为4(0100)的权限权限总和
       1011
    & 0100
       0000 = 0 (没有操作权限)
     
    通过上面的例子不难发现:每一项权限(权限码) 对应一个二进制位,权限总和则表示用户拥有的所有权限(权限码)的二进制位。在进行比对的时候,某一个权限对应的权限码与权限总和进行“与运算”,即可说明用户是否有该权限。
     
    致命的缺点:从上面的情况不难看出,数据库和Java程序中有符号的长整型最大为 2^63-1 加上原来的1 最多只可能有63(62+1)条权限。但这在实际的应用中63条权限显然是不够的。
     
    解决的办法:
    1>给权限表添加一项权限组字段(rpos)
    2>该字段从0开始,当权限码数量即将要满的时候,该字段加一
    3>这样就可以有 n*63(63这里是最大值可以适当缩小)
    4>用户权限总和采用long[]数组进行存储,每一权限组对应数组的下标。
    例如:
     public boolean hasRight(Rights r) {
         return (rigths[r.getRpos()] & r.getRcode()) != 0;
     }
     
    可将所有权限缓存在Nosql(redis)数据库中,每次需要比对的时候去Nosql数据库中查询,这样一来,减少mysql(主服务器)的压力,二来Nosql数据库检索的速度是非常高效的。
  • 相关阅读:
    大数据量磁盘文件排序
    Unix文件系统基本结构
    TCP三次握手和四次挥手
    哈希表的尴尬
    Http Get/Post请求的区别
    关于数据仓库中缓慢变化维的总结
    客户端回调过程..
    有关闭包的理解
    OWA半中文半英文问题,OWA实现邮件群发问题
    win2k3卷影副本服务的使用
  • 原文地址:https://www.cnblogs.com/everyingo/p/12791356.html
Copyright © 2011-2022 走看看