不论是在网站开发仍是MIS系统开发中,涉及到多用户的软件系统都会遇到这个问题,如何比较优雅的解决这个问题也一直是你们常常探讨的热门话题,本文试着谈论一下本身的观点,但愿和你们共同切磋。
方法一: 用户表: T_UserInfo id name 对象表: T_Object id name 权限表 T_Access accessid userid(外键,来自用户表) objectid(外键,来自对象表) access(用代码记录用户的权限组合: 1000 浏览 1100 浏览、添加 1110 浏览、添加、编辑 1111 浏览、添加、编辑、删除 等) 方法二: 用户表: T_UserInfo id name 对象表: T_Object id name access1(表明浏览,保存用户的id号,用逗号分隔) access2(表明浏览、添加) access3(表明浏览、添加、编辑) access4(表明浏览、添加、编辑、删除) 孰优孰劣? --------------------------------------------------------------- 我們用的是第一種 WINDOWS系統用的也是第一種 --------------------------------------------------------------- 方法2不可取,用户增长的时候很是麻烦,并且access1--access4的长度很难肯定。
下面我要说的是MIS系统权限管理的数据库设计及实现,固然,这些思路也能够推广开来应用,好比说在BBS中用来管理不一样级别的用户权限。
权限设计一般包括数据库设计、应用程序接口(API)设计、程序实现三个部分。
这三个部分相互依存,密不可分,要实现完善的权限管理体系,必须考虑到每个环节可行性与复杂程度甚至执行效率。
咱们将权限分类,首先是针对数据存取的权限,一般有录入、浏览、修改、删除四种,其次是功能,它能够包括例如统计等全部非直接数据存取操做,另外,咱们还可能对一些关键数据表某些字段的存取进行限制。除此,我想不出还有另外种类的权限类别。
完善的权限设计应该具备充分的可扩展性,也就是说,系统增长了新的其它功能不该该对整个权限管理体系带来较大的变化,要达到这个目的,首先是数据库设计合理,其次是应用程序接口规范。
咱们先讨论数据库设计。一般咱们使用关系数据库,这里不讨论基于Lotus产品的权限管理。
权限表及相关内容大致能够用六个表来描述,以下: 1 角色(即用户组)表:包括三个字段,ID,角色名,对该角色的描述; 2 用户表:包括三个或以上字段,ID,用户名,对该用户的描述,其它(如地址、电话等信息); 3 角色-用户对应表:该表记录用户与角色之间的对应关系,一个用户能够隶属于多个角色,一个角色组也可拥有多个用户。包括三个字段,ID,角色ID,用户ID; 4 限制内容列表:该表记录全部须要加以权限区分限制的数据表、功能和字段等内容及其描述,包括三个字段,ID,名称,描述; 5 权限列表:该表记录全部要加以控制的权限,如录入、修改、删除、执行等,也包括三个字段,ID,名称,描述; 6 权限-角色-用户对应表:通常状况下,咱们对角色/用户所拥有的权限作以下规定,角色拥有明令容许的权限,其它一概禁止,用户继承所属角色的所有权限,在此范围内的权限除明令禁止外所有容许,范围外权限除明令容许外所有禁止。该表的设计是权限管理的重点,设计的思路也不少,能够说各有千秋,不能生搬硬套说某种方法好。对此,个人见解是就我的状况,找本身以为合适能解决问题的用。
先说第一种也是最容易理解的方法,设计五个字段:ID,限制内容ID,权限ID,角色/用户类型(布尔型字段,用来描述一条记录记录的是角色权限仍是用户权限),角色/用户ID,权限类型(布尔型字段,用来描述一条记录表示容许仍是禁止)
好了,有这六个表,根据表六,咱们就能够知道某个角色/用户到底拥有/禁止某种权限。
或者说,这么设计已经足够了,咱们彻底实现了所须要的功能:能够对角色和用户分别进行权限定制,也具备至关的可扩展性,好比说增长了新功能,咱们只须要添加一条或者几条记录就能够,同时应用程序接口也无须改动,具备至关的可行性。
可是,在程序实现的过程当中,咱们发现,使用这种方法并非十分科学,例如浏览某个用户所拥有的权限时,须要对数据库进行屡次(甚至是递归)查询,极不方便。因而咱们须要想其它的办法。使用过Unix系统的人们都知道,Unix文件系统将对文件的操做权限分为三种:读、写和执行,分别用一、二、4三个代码标识,对用户同时具备读写权限的文件被记录为3,即1+2。咱们也能够用相似的办法来解决这个问题。初步的想法是修改权限列表,加入一个字段:标识码,例如,咱们能够将录入权限标识为1,浏览权限标识为2,修改权限标识为4,删除权限标识为8,执行权限标识为16,这样,咱们经过权限累加的办法就能够轻易的将本来要分为几条记录描述的权限放在一块儿了,例如,假定某用户ID为1,库存表对应的限制内容ID为2,同时规定角色类型为0、用户类型为1,咱们就能够将该用户具备录入、浏览、修改、删除库存表的权限描述为:2,15,1,1。
确实很简单,不是吗?甚至还有更过激的办法,将限制内容列表也加上一列,定义好标识码,这样,咱们甚至能够用简单的一条记录描述某个用户具备的对所有内容所具备的所有权限了。固然,这样作的前提是限制内容数量比较小,否则,呵呵,2的n次方递增起来但是数量惊人,不容易解析的。
从表面上看,上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的,但这样作有个弊端,咱们所涉及的权限列表不是相互独立而是互相依赖的,好比说修改权限,实际上是包含浏览权限的,例如,咱们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除(1+4+8=13),但事实上,该用户具备(1+2+4+8=15)的权限,也就是说,在这种方案中,13=15。因而当咱们调用API询问某用户是否具备浏览权限时,就必须判断该用户是否具备对该数据表的修改权限,所以,若是不能在程序中固化权限之间的包含关系,就不能利用应用程序接口简单的作出判断。但这与咱们的目的“充分的可扩展性”矛盾。
这个问题如何解决?我想到了另一种设置标识码的方法,那就是利用素数。咱们不妨将录入、浏览、修改、删除、执行的基本标志码定为2,3,5,7,11,当遇到权限互相包含的时候,咱们将它的标识码设定为两个(或多个)基本标志码的乘积,例如,能够将“修改”功能的标志码定为3*5=15,而后将全部的权限相乘,就获得了咱们须要的最终权限标识值。这样,咱们在询问用户是否具备某项权限的时候,只须要将最终的值分解成质因子,例如,咱们能够定义一个用户具备录入+修改+删除库存表的权限为 2*15*7=2*3*5*7,即表示,该用户具备了对库存表录入+浏览+修改+删除权限。
固然,对权限列表咱们使用上述方法的前提是权限列表记录条数不会太多而且关系不是十分复杂,不然,光是解析权限代码就要机器忽悠半宿:)
我但愿以上的分析是正确且有效的(事实上,我也用这些的方法在不止一套系统中实现),但不管如何,我以为如此实现权限管理,只是考虑了数据库设计和应用程序接口两部份内容,对于实现,仍是显得很费劲。所以,我恳请有过相似设计、实现经验的同志们提出建设性的意见和修改建议。
http://zhoufoxcn.blog.51cto.com/792419/166431/