最近在考虑使用权限系统管理网站,使用公司的一些权限系统,感觉操作复杂,操作速度极慢,业务也跟着慢了很多。基于这些顽疾,最近稍闲,决定自己想办法设计一套。
权限就得从用户说起,最简单的:用户有没有权限看某个菜单,点击某个按钮,查看某条数据···这是权限系统最基本的体现——最简单地达到目的,减少数据库读取次数,简单即真理。
要管理用户权限,这里我们就不得不引入用户一个属性——角色;用户和角色是一个多对多的关系;这里就需要引入一个用户和角色的中间表;
在数据库设计里,到目前位置我们创建了3张表了(用户表、角色表、角色用户关系表)。
我们通过给角色添加权限,最后反映在登录的用户身上;
接下来我们就要讲到权限了,网站类权限,最关键的就是权限量化;在这我将权限分为两大类:菜单权限和数据权限。
首先说菜单权限:某个用户能否看某些菜单,流程是这样的:用户——角色——权限——菜单(感觉层级太多,又是多对多关系,我再屡屡)
select * from 菜单 M
join 权限 Q on M.ID=Q.MID
join 角色 J on J.QID=Q.ID
join 用户 U on U.JID=J.ID
where U.Code=登录名
这关系到一个权限系统 的管理粒度大小问题,当我写出上面这个SQL,又细想了一遍,为了更好地管理也很难再简化了。是inner join关系,用户、菜单、权限和角色这类系统表基本上不大,改动量也不会太多,可以存放在Memcache或者Redis等其他缓存上,效率能进一步优化下。
接下来我们做单个菜单的操作权限:增删改查、导出、打印、审批等等功能。
菜单权限里面,权限表我是这样设计的:权限名称、菜单ID、增、删、改、查·····ALL。
意思就是:这个权限管理这个菜单的一些列操作,当操作的值为1,则可操作,0不可操作,ALL为1就是可操作全部。
当然这里面还存在某些特殊操作类型,具体问题具体分析了,设计之初预留一些备用字段。
这样在打开某个菜单的时候,我们控制操作权限的逻辑就是这样的:
select * from 权限 Q
join 角色 J on J.QID=Q.ID
join 用户 U on U.JID=J.ID
where Q.MID=菜单ID AND U.Code=登录名
这样在加载页面的时候根据这个对象Model来控制操作即可。
接下来讨论我们设计数据权限
相对于菜单权限,其实数据权限的个性化更强;
结合菜单权限的思路,这里我想走单表控制的逻辑;
数据权限表结构:权限明、表名、字段名1、限制条件1、值1、字段名2、限制条件2、值2····
这里面存在一个问题,比如,查询某个业务时,需要join多个表,就需要把这些表的权限限制都查出来,会增加数据库读取次数和业务复杂度。
这样查询数据的时候首先需要找出查询条件,再查询数据。在前端非IT用户编辑的时候设计操作方式也存在一些潜在特殊业务的可能性。
这方面我经验还比较欠缺,下次有机会再加强点,再来完善这篇文章吧!