﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-枫言枫语-文章分类-数据库</title><link>http://www.blogjava.net/zpq/category/24626.html</link><description>——  by 玉澍淋枫</description><language>zh-cn</language><lastBuildDate>Tue, 14 Aug 2007 06:14:38 GMT</lastBuildDate><pubDate>Tue, 14 Aug 2007 06:14:38 GMT</pubDate><ttl>60</ttl><item><title>关于权限的数据库设计</title><link>http://www.blogjava.net/zpq/articles/134326.html</link><dc:creator>玉澍淋枫</dc:creator><author>玉澍淋枫</author><pubDate>Fri, 03 Aug 2007 12:43:00 GMT</pubDate><guid>http://www.blogjava.net/zpq/articles/134326.html</guid><wfw:comment>http://www.blogjava.net/zpq/comments/134326.html</wfw:comment><comments>http://www.blogjava.net/zpq/articles/134326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zpq/comments/commentRss/134326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zpq/services/trackbacks/134326.html</trackback:ping><description><![CDATA[<br>
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
<div class="postTitle">		<a href="http://blog.csdn.net/zhoufoxcn/archive/2007/03/21/1536110.aspx"><img src="http://blog.csdn.net/images/authorship.gif" border="0" height="13" width="15">&nbsp;关于权限的数据库设计</a>	</div>
<p>不管是在网站开发还是MIS系统开发中，涉及到多用户的软件系统都会遇到这个问题，如何比较优雅的解决这个问题也一直是大家经常探讨的热门话题，本文试着谈论一下自己的观点，希望和大家共同切磋。</p>
<p>方法一：&nbsp; <br>&nbsp;<br>用户表：&nbsp; <br>T_UserInfo&nbsp; <br>&nbsp;&nbsp; id&nbsp; <br>&nbsp;&nbsp; name&nbsp; <br>&nbsp;<br>对象表:&nbsp; <br>T_Object&nbsp; <br>&nbsp;&nbsp; id&nbsp; <br>&nbsp;&nbsp; name&nbsp; <br>&nbsp;<br>权限表&nbsp; <br>T_Access&nbsp; <br>&nbsp;&nbsp; accessid&nbsp; <br>&nbsp;&nbsp; userid（外键，来自用户表）&nbsp; <br>&nbsp;&nbsp; objectid（外键，来自对象表）&nbsp; <br>&nbsp;&nbsp; access(用代码记录用户的权限组合：&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000&nbsp; 浏览&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1100&nbsp; 浏览、添加&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1110&nbsp; 浏览、添加、编辑&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1111&nbsp; 浏览、添加、编辑、删除&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 等)&nbsp; <br>&nbsp;<br>方法二：&nbsp; <br>&nbsp;<br>用户表：&nbsp; <br>T_UserInfo&nbsp; <br>&nbsp;&nbsp; id&nbsp; <br>&nbsp;&nbsp; name&nbsp; <br>&nbsp;<br>对象表:&nbsp; <br>T_Object&nbsp; <br>&nbsp;&nbsp; id&nbsp; <br>&nbsp;&nbsp; name&nbsp; <br>&nbsp;&nbsp; access1(代表浏览，保存用户的id号，用逗号分隔)&nbsp; <br>&nbsp;&nbsp; access2(代表浏览、添加)&nbsp; <br>&nbsp;&nbsp; access3(代表浏览、添加、编辑)&nbsp; <br>&nbsp;&nbsp; access4(代表浏览、添加、编辑、删除)&nbsp; <br>&nbsp;<br>孰优孰劣？&nbsp; <br>---------------------------------------------------------------&nbsp; <br>&nbsp;<br>我們用的是第一種&nbsp; <br>WINDOWS系統用的也是第一種&nbsp; <br>&nbsp;<br>&nbsp;<br>---------------------------------------------------------------&nbsp; <br>&nbsp;<br>方法2不可取，用户增加的时候非常麻烦，而且access1--access4的长度很难确定。&nbsp;&nbsp;</p>
<p>下面我要说的是MIS系统权限管理的数据库设计及实现，当然，这些思路也可以推广开来应用，比如说在BBS中用来管理不同级别的用户权限。 </p>
<p>权限设计通常包括数据库设计、应用程序接口(API)设计、程序实现三个部分。 </p>
<p>这三个部分相互依存，密不可分，要实现完善的权限管理体系，必须考虑到每一个环节可行性与复杂程度甚至执行效率。 </p>
<p>我们将权限分类，首先是针对数据存取的权限，通常有录入、浏览、修改、删除四种，其次是功能，它可以包括例如统计等所有非直接数据存取操作，另外，我们还可能对一些关键数据表某些字段的存取进行限制。除此，我想不出还有另外种类的权限类别。 </p>
<p>完善的权限设计应该具有充分的可扩展性，也就是说，系统增加了新的其它功能不应该对整个权限管理体系带来较大的变化，要达到这个目的，首先是数据库设计合理，其次是应用程序接口规范。 </p>
<p>我们先讨论数据库设计。通常我们使用关系数据库，这里不讨论基于Lotus产品的权限管理。 </p>
<p>权限表及相关内容大体可以用六个表来描述，如下： <br>1 角色（即用户组）表：包括三个字段，ID，角色名，对该角色的描述； <br>2 用户表：包括三个或以上字段，ID，用户名，对该用户的描述，其它（如地址、电话等信息）； <br>3 角色-用户对应表：该表记录用户与角色之间的对应关系，一个用户可以隶属于多个角色，一个角色组也可拥有多个用户。包括三个字段，ID，角色ID，用户ID； <br>4 限制内容列表：该表记录所有需要加以权限区分限制的数据表、功能和字段等内容及其描述，包括三个字段，ID，名称，描述； <br>5 权限列表：该表记录所有要加以控制的权限，如录入、修改、删除、执行等，也包括三个字段，ID，名称，描述； <br>6
权限-角色-用户对应表：一般情况下，我们对角色/用户所拥有的权限做如下规定，角色拥有明令允许的权限，其它一律禁止，用户继承所属角色的全部权限，在
此范围内的权限除明令禁止外全部允许，范围外权限除明令允许外全部禁止。该表的设计是权限管理的重点，设计的思路也很多，可以说各有千秋，不能生搬硬套说
某种方法好。对此，我的看法是就个人情况，找自己觉得合适能解决问题的用。 </p>
<p>先说第一种也是最容易理解的方法，设计五个字段：ID，限制内容ID，权限ID，角色/用户类型（布尔型字段，用来描述一条记录记录的是角色权限还是用户权限），角色/用户ID，权限类型（布尔型字段，用来描述一条记录表示允许还是禁止） </p>
<p>好了，有这六个表，根据表六，我们就可以知道某个角色/用户到底拥有/禁止某种权限。 </p>
<p>或
者说，这么设计已经足够了，我们完全实现了所需要的功能：可以对角色和用户分别进行权限定制，也具有相当的可扩展性，比如说增加了新功能，我们只需要添加
一条或者几条记录就可以，同时应用程序接口也无须改动，具有相当的可行性。但是，在程序实现的过程中，我们发现，使用这种方法并不是十分科学，例如浏览某
个用户所拥有的权限时，需要对数据库进行多次（甚至是递归）查询，极不方便。于是我们需要想其它的办法。使用过Unix系统的人们都知道，Unix文件系
统将对文件的操作权限分为三种：读、写和执行，分别用1、2、4三个代码标识，对用户同时具有读写权限的文件被记录为3，即1+2。我们也可以用类似的办
法来解决这个问题。初步的想法是修改权限列表，加入一个字段：标识码，例如，我们可以将录入权限标识为1，浏览权限标识为2，修改权限标识为4，删除权限
标识为8，执行权限标识为16，这样，我们通过权限累加的办法就可以轻易的将原本要分为几条记录描述的权限放在一起了，例如，假定某用户ID为1，库存表
对应的限制内容ID为2，同时规定角色类型为0、用户类型为1，我们就可以将该用户具有录入、浏览、修改、删除库存表的权限描述为：2,15,1,1。
</p>
<p>确实很简单，不是吗？甚至还有更过激的办法，将限制内容列表也加上一列，定义好标识码，这样，我们甚至可以用简单的一条记录描述某个用户具
有的对全部内容所具有的全部权限了。当然，这样做的前提是限制内容数量比较小，不然，呵呵，2的n次方递增起来可是数量惊人，不容易解析的。 </p>
<p>从
表面上看，上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的，但这样做有个弊端，我们所涉及的权限列表不是相互独立而是互相依赖的，比如
说修改权限，其实是包含浏览权限的，例如，我们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除（1+4+8=13),但事实上，该用户具
有(1+2+4+8=15）的权限，也就是说，在这种方案中，13=15。于是当我们调用API询问某用户是否具有浏览权限时，就必须判断该用户是否具有
对该数据表的修改权限，因此，如果不能在程序中固化权限之间的包含关系，就不能利用应用程序接口简单的做出判断。但这与我们的目的&#8220;充分的可扩展性&#8221;矛
盾。 </p>
<p>这个问题如何解决？我想到了另外一种设置标识码的方法，那就是利用素数。我们不妨将录入、浏览、修改、删除、执行的基本标志码定为
2,3,5,7,11，当遇到权限互相包含的时候，我们将它的标识码设定为两个（或多个）基本标志码的乘积，例如，可以将&#8220;修改&#8221;功能的标志码定为3*5
=15，然后将所有的权限相乘，就得到了我们需要的最终权限标识值。这样，我们在询问用户是否具有某项权限的时候，只需要将最终的值分解成质因子，例如，
我们可以定义一个用户具有录入+修改+删除库存表的权限为 2*15*7=2*3*5*7，即表示，该用户具有了对库存表录入+浏览+修改+删除权限。
</p>
<p>当然，对权限列表我们使用上述方法的前提是权限列表记录条数不会太多并且关系不是十分复杂，否则，光是解析权限代码就要机器忽悠半宿：） </p>
<p>我
希望以上的分析是正确且有效的（事实上，我也用这些的方法在不止一套系统中实现），但无论如何，我觉得如此实现权限管理，只是考虑了数据库设计和应用程序
接口两部分内容，对于实现，还是显得很费劲。因此，我恳请有过类似设计、实现经验的同志们提出建设性的意见和修改建议。</p>
<br><br>
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1536110</p><img src ="http://www.blogjava.net/zpq/aggbug/134326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zpq/" target="_blank">玉澍淋枫</a> 2007-08-03 20:43 <a href="http://www.blogjava.net/zpq/articles/134326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实现业务系统中的用户权限管理--实现篇</title><link>http://www.blogjava.net/zpq/articles/134321.html</link><dc:creator>玉澍淋枫</dc:creator><author>玉澍淋枫</author><pubDate>Fri, 03 Aug 2007 12:11:00 GMT</pubDate><guid>http://www.blogjava.net/zpq/articles/134321.html</guid><wfw:comment>http://www.blogjava.net/zpq/comments/134321.html</wfw:comment><comments>http://www.blogjava.net/zpq/articles/134321.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zpq/comments/commentRss/134321.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zpq/services/trackbacks/134321.html</trackback:ping><description><![CDATA[<p><strong>实现业务系统中的用户权限管理--实现篇</strong>                          </p>
<p align="left"><font size="2"><strong>　　</strong></font>在设计篇中，我们已经为大家阐述了有关权限管理系统的数据库设计，在本篇中，我们将重点放在其实现代码部分。为了让你能够更直接更有效的看到全部动作的代码，我们使用&#8220;动作分解列表&#8221;的方式来陈述每个动作以及相关资源。</p>
<p align="left"><strong>实现权限管理功能的动作</strong></p>
<table style="font-size: 12px;" border="1" width="100%">
    <tbody>
        <tr align="center" bgcolor="#cccccc">
            <td><strong>动作分解</strong></td>
            <td><strong>动作名</strong></td>
            <td><strong>相关表名</strong></td>
            <td><strong>操作集类型<br>
            (S,U,I,D,SQL)</strong></td>
            <td><strong>表单</strong></td>
            <td><strong>模组</strong></td>
            <td><strong>字符资源</strong></td>
            <td><strong>是否分页？</strong></td>
            <td><strong>返回提示？</strong></td>
            <td><strong>权限检测</strong></td>
        </tr>
        <tr align="center">
            <td>权限初始化安装</td>
            <td><span class="code"><a href="http://docs.noahweb.net/ProjectA/setup.html" target="_blank">setup</a></span></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/msetup.html" target="_blank">setup</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/setupok.html" target="_blank">setupok</a></td>
            <td>否</td>
            <td>否</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>显示添加管理组界面</td>
            <td><a href="http://docs.noahweb.net/ProjectA/addnewgroup.html" target="_blank">addnewgroup</a></td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/addgroup.html" target="_blank">addgroup</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>无</td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行添加管理员动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/addnewgroup_ex.html" target="_blank">addnewgroup_ex</a></td>
            <td>gorupmanager、gorupmanager、mastergroup</td>
            <td>S、I、I</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/addok.html" target="_blank">addok</a> <a href="http://docs.noahweb.net/ProjectA/adderror.html" target="_blank"><br>
            adderror</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示所有管理组列表以执行设置权限动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setgroupinfo.html" target="_blank">setgroupinfo</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/list_allgroup.html" target="_blank">list_allgroup</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示设置管理组权限界面</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setgroupinfo_input.html" target="_blank">setgroupinfo_input</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/list_allgrouppurview.html" target="_blank">list_allgrouppurview</a> <a href="http://docs.noahweb.net/ProjectA/del_confirm.html" target="_blank"><br>
            del_confirm</a></p>
            </td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行设置管理组权限动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setgroupinfo_ok.html" target="_blank">setgroupinfo_ex</a></td>
            <td>actiongroup、action、actiongroup</td>
            <td>D、S、I</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setgrouppurview.html" target="_blank">setgrouppurview</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/loginjumpframe.html" target="_blank">loginjumpframe</a></p>
            </td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行删除管理组动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/delgroup_ex.html" target="_blank">delgroup_ex</a></td>
            <td>groupmaster、actiongroup</td>
            <td>D、D</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a> <a href="http://docs.noahweb.net/ProjectA/checkpointid.html" target="_blank">checkpointid</a></p>
            </td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/list_allgroup.html" target="_blank">list_allgroup</a></p>
            </td>
            <td>是</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示所有管理组列表以执行查看管理组成员动作</td>
            <td><span class="code"><a href="http://docs.noahweb.net/ProjectA/viewgroupmaster.html" target="_blank">viewgroupmaster</a></span></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <a href="http://docs.noahweb.net/ProjectA/list_allgroup.html" target="_blank"><br>
            list_allgroup</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>查看所选择管理组下的所有成员</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/viewmaster.html" target="_blank">viewmaster</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/listgroupmaster.html" target="_blank">list_groupmaster</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>显示添加管理员界面</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/addnewmaster.html" target="_blank">addnewmaster</a></td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/addnewmasterform.html" target="_blank">addnewmaster</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>无</td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行添加管理员动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/addnewmaster_ok.html" target="_blank">addnewmaster_ex</a></td>
            <td>master、master、mastergroup</td>
            <td>S、I、I</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/addok.html" target="_blank">addok</a><br>
            <a href="http://docs.noahweb.net/ProjectA/adderror.html" target="_blank">adderror</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示所有管理员列表以执行设置管理员权限动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">setmasterpurview</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/list_allmaster.html" target="_blank">list_allmaster</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>查看所选择管理员所在管理组</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview_input.html" target="_blank">setmasterpurview_input</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/listmastergroup.html" target="_blank">list_mastergroup</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>执行设置所选管理员权限</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview_ok.html" target="_blank">setmasterpurview_ex</a></td>
            <td>mastergroup、mastergroup</td>
            <td>D、I</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/loginjumpframe.html" target="_blank">loginjumpframe</a>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示所有管理员列表以执行设置管理员密码动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpass.html" target="_blank">setmasterpass</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a><br><a href="http://docs.noahweb.net/ProjectA/list_allmaster.html" target="_blank">list_allmaster</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>显示密码修改界面</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpass_input.html" target="_blank">setmasterpass_input</a></td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/masterpassword.html" target="_blank">masterpassword</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>无</td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>执行修改管理员密码动作</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpass_ok.html" target="_blank">setmasterpass_ex</a></td>
            <td>master</td>
            <td>SQL</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>显示所有管理员列表以执行修改管理员信息动作</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterinfo.html" target="_blank">setmasterinfo</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a><br> <a href="http://docs.noahweb.net/ProjectA/list_allmaster.html" target="_blank">list_allmaster</a></p>
            </td>
            <td>是</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>显示所选择管理员信息修改界面</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterinfo_input.html" target="_blank">setmasterinfo_input</a></td>
            <td>master</td>
            <td>S</td>
            <td><a href="http://docs.noahweb.net/ProjectA/editmasterinfo.html" target="_blank">editmasterinfo</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/del_confirm.html" target="_blank">del_confirm</a></td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>
            <p>执行修改管理员信息动作</p>
            </td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterinfo_ok.html" target="_blank">setmasterinfo_ex</a></td>
            <td>master</td>
            <td>U</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a></td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a><br>
            <a href="http://docs.noahweb.net/ProjectA/list_allmaster.html" target="_blank">list_allmaster</a>
            </td>
            <td>是</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行删除管理组动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/delmaster_ex.html" target="_blank">delmaster_ex</a></td>
            <td>master、actiongroup</td>
            <td>D、D</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a> <a href="http://docs.noahweb.net/ProjectA/checkpointid.html" target="_blank">checkpointid</a></p>
            </td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/setmasterpurview.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/list_allmaster.html" target="_blank">list_allmaster</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行修改当前管理员密码动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmyinfo_ok.html" target="_blank">setmyinfo_ex</a></td>
            <td>master</td>
            <td>U</td>
            <td>无</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示修改当前管理员信息界面</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmyinfo.html" target="_blank">setmyinfo</a></td>
            <td>master</td>
            <td>S</td>
            <td><a href="http://docs.noahweb.net/ProjectA/editmasterinfo.html" target="_blank">editmasterinfo</a></td>
            <td>无</td>
            <td>无</td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>执行修改当前管理员密码动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmypass_ok.html" target="_blank">setmypass_ex</a></td>
            <td>master</td>
            <td>SQL</td>
            <td>无</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/viewtitle.html" target="_blank">viewtitle</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/do_ok.html" target="_blank">do_ok</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>是</td>
        </tr>
        <tr align="center">
            <td>显示修改当前管理员密码界面</td>
            <td><a href="http://docs.noahweb.net/ProjectA/setmypass.html" target="_blank">setmypass</a></td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/masterpassword.html" target="_blank">masterpassword</a></td>
            <td>无</td>
            <td>无</td>
            <td>否</td>
            <td>否</td>
            <td>是</td>
        </tr>
    </tbody>
</table>
<p align="left"><strong>系统动作</strong></p>
<table style="font-size: 12px;" border="1" width="100%">
    <tbody>
        <tr align="center" bgcolor="#cccccc">
            <td><strong>动作分解</strong></td>
            <td><strong>动作名</strong></td>
            <td><strong>相关表名</strong></td>
            <td><strong>操作集类型<br>
            (S,U,I,D,SQL)</strong></td>
            <td><strong>表单</strong></td>
            <td><strong>模组</strong></td>
            <td><strong>字符资源</strong></td>
            <td><strong>是否分页？</strong></td>
            <td><strong>返回提示？</strong></td>
            <td><strong>权限检测</strong></td>
        </tr>
        <tr align="center">
            <td>当管理员第一次进入管理系统时将使用该动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/first.html" target="_blank">*</a></td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/loginform.html" target="_blank">login</a></td>
            <td>无</td>
            <td>无</td>
            <td>否</td>
            <td>否</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>系统登录动作，管理员登录系时将使用该动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/login.html" target="_blank">login</a></td>
            <td>master</td>
            <td>SQL</td>
            <td>无</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/loginok.html" target="_blank">loginok</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/loginjumpframe.html" target="_blank">loginjumpframe</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/loginerror.html" target="_blank">loginerror</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>显示窗口TITLE信息</td>
            <td><a href="http://docs.noahweb.net/ProjectA/viewtoolstitle.html" target="_blank">viewtoolstitle</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/managertitle.html" target="_blank">managertitle</a></td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>显示左工具条</td>
            <td><a href="http://www.noahweb.net/mail/2/list_tools" target="_blank">list_tools</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>任务系统（预留）</td>
            <td>autoviewtask</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr align="center">
            <td>当用户未进行登录而执行动作时会引发该动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/nosession.html" target="_blank">nosession</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/nosessiontext.html" target="_blank">nosession</a><br>
            <a href="http://docs.noahweb.net/ProjectA/nosessionjumpframe.html" target="_blank">nosessionjumpframe</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>当用户进行删除操作时未点击确认时会引发该动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/nopointid.html" target="_blank">nopointid</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/nopointidtext.html" target="_blank">nopointid</a></td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>当用户试图执行自己没有权限执行的动作时会引发该动作</td>
            <td><a href="http://docs.noahweb.net/ProjectA/nopurview.html" target="_blank">nopurview</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td><a href="http://docs.noahweb.net/ProjectA/nopurviewtext.html" target="_blank">nopurview</a></td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
        <tr align="center">
            <td>退出系统</td>
            <td><a href="http://docs.noahweb.net/ProjectA/outlogin.html" target="_blank">outlogin</a></td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>无</td>
            <td>
            <p><a href="http://docs.noahweb.net/ProjectA/loginout.html" target="_blank">loginout</a> <br>
            <a href="http://docs.noahweb.net/ProjectA/nosessionjumpframe.html" target="_blank">nosessionjumpframe</a></p>
            </td>
            <td>否</td>
            <td>是</td>
            <td>否</td>
        </tr>
    </tbody>
</table>
<p align="left"><strong>详解模组</strong>：</p>
<p align="left">　　1.<strong>setup(数据库初始化、权限设置模组)</strong></p>
<p align="left">　　当布署好一个新的系统后，我们可以通过执行一个动作setup来安装数据库和一些初始值，通过执行这个动作系统可以正常运行。因为执行setup这个动作时会调用到一个名称为<a href="http://docs.noahweb.net/ProjectA/msetup.html">setup</a>的模组，这个模组的作用是初始化系统所用到的数据库，并且在系统中设置动作的权限，否则数据库和有权限的动作就没办法执行。下面我们来看一下setup模组的代码，<a href="http://docs.noahweb.net/ProjectA/msetup.html">点击这里查看代码</a>。这里我们把代码拆分开看一下，由于setup模组里有好多类似的代码，所以这里我们只找出不同功能的代码做一下介绍：</p>
<p align="left">　　第一段：数据库安装</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m1.gif" height="29" width="257"></p>
<p align="left">　　在模组中首先调用了一个datebase_SQL_setup这个数据库操作集，这个数据库操作集用来为系统中的数据库表（根据情况删除或新建）做初始化。</p>
<p align="left">　　第二段：添加权限信息</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m2.gif" height="156" width="438"></p>
<p align="left">　　代码中调用了action_I_newone这个数据库操作集，在这个操作集中加入权限的名称和它的其它信息。</p>
<p align="left">　　第三段：添加一个管理员</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m3.gif" height="515" width="441"></p>
<p align="left">　　这部分代码中调用了master_I_newone数据库操作集在数据库中添加了一个管理员的信息，这个信息是可以不写在这里的，可以直接在数据库中添加，但是为了减少不必要的麻烦所以直接在这里添入了一个默认的管理员。</p>
<p align="left">　　第四段：添加管理员组</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m4.gif" height="187" width="411"></p>
<p align="left">　　通过调用groupmanager_I_newmaster这个数据库操作集新建了一个管理员组，并加入了详细的管理员组信息，可以把新用户加入到此管理员组。</p>
<p align="left">　　第五段：添加新的工具分栏</p>
<p align="left">　　<img src="http://www.noahweb.net/mail/2/m5.gif" height="69" width="439"></p>
<p align="left">　　通过调用actioncolumn_I_newone数据库操作集在工具栏里加入一个工具栏分栏选项。</p>
<p align="left">　　第六段：指定管理组</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m6.gif" height="215" width="415"></p>
<p align="left">　　通过调用mastergroup_I_newone数据库操作集把admin这个用户加入到第一个管理组里，使该用户成为第一个管理组的成员。</p>
<p align="left">　　最后一段：指定管理组拥有的权限</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/m7.gif" height="231" width="453"></p>
<p align="left">　　这段代码首先调用了action_S_all数据库操作集并使用Loop语句列出所有的动作，然后调用actiongroup_I_newone这个数据库操作集，把所有的动作都加入到第一个管理组里，使第一个管理组拥有所有权限。</p>
<p align="left">　　这里之所以把数据库的安装和权限的设置都放在模组里面，是为了使用户使用更加方便，不需要再去重新手动建库，以减不在数据库这方面的错误，使系统更加简单流畅。如果其它系统也需要权限这方面的管理，可以把模组稍做修改就可以直接拿来用，这样也体现出代码的重用性。</p>
<p align="left">&nbsp;</p>
<p align="left"><strong> 　　2.checkuserpurview（检验当前用户能否执行该动作的模组）</strong></p>
<p align="left"><font size="2"><strong>　　</strong></font>在权限管理系统中，模组<a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a>得到了反复使用，该模组担负着检测用户权限的任务，在所有需要进行访问权限控制的动作的开始部分都调用了该模组，所以理解该模组的代码也有一定难度。下面，我们来看一看该模组的代码。</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/checkuserpurview.gif" height="332" width="443"></p>
<p align="left"><font size="2"><strong>　　</strong></font>我们将整段代码拆分一下，首先看第一段，如下图：</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/checkuserpurview_1.gif" height="61" width="328"></p>
<p align="left"><font size="2"><strong>　　</strong></font>判断_SESSION.myloginid的值是否为空，如果为空，在当前页面中执行<a href="http://docs.noahweb.net/ProjectA/nosession.html" target="_blank">nosession</a>这个动作。我们在用户登陆的动作中<a href="http://docs.noahweb.net/ProjectA/login.html" target="_blank">login</a>会为登陆的用户使用myloginid的SESSION变量记录下该用户的ID，因此如果用户是正常登陆并在SESSION有效期内的话，则_SESSION.myloginid的值是不可能为空的。通过此部分代码检测用户是否已经登陆成功并获得合法的访问身份。</p>
<p align="left"><font size="2"><strong>　　</strong></font>然后看下面的代码，如下图：</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/checkuserpurview_2.gif" height="183" width="436"></p>
<p align="left"><font size="2"><strong>　　</strong></font>调
用数据库操作集mastergroup_S_bymasterid，使用逻辑层的Loop，使用当前执行的action以及查询返回的groupid作为
条件，调用数据库操作集actiongroup_S_byactionandgroupid进行循环查询，如果查询返回值大于0（零），将局部变量
purview的值设置为1。</p>
<p align="left"><font size="2"><strong>　　</strong></font>这
段代码的重点在于使用的Loop进行循环，由于actiongroup表中记录着用户所处的管理组能够执行的权限，并且一个用户可能同时会属于多个组，因
此我们需要去检验用户属于的多个组中是否有对该动作执行的权限，因此，我们使用当前需要执行的动作action以及用户所处的管理组groupid循环查
询，当前用户所属于的组中只要有一个组具有执行该动作的执行权限，则该用户就可以执行该动作。</p>
<p align="left"><font size="2"><strong>　　</strong></font>最后一部分代码如下图：</p>
<p align="left"><img src="http://www.noahweb.net/mail/2/checkuserpurview_3.gif" height="62" width="310"></p>
<p align="left"><font size="2"><strong>　　</strong></font>再次使用判断，如果purview的值不为1的话，则在当前页面执行<a href="http://docs.noahweb.net/ProjectA/nopurview.html" target="_blank">nopurview</a>动作。</p>
<p align="left"><font size="2"><strong>　　</strong></font>由于之前的代码中，如果用户拥有执行动作的权限的话，会将局部变量purview的值设置为1，所以这里如果该变量值不为1，就说明了此用户没有执行动作的权限，故执行<a href="http://docs.noahweb.net/ProjectA/nopurview.html" target="_blank">nopurview</a>动作。</p>
<p align="left"><strong>总结</strong></p>
<p align="left"><font size="2"><strong>　　</strong></font>从设计到实现，权限管理系统的教程到这里就全部结束了。在设计阶段，最重要也是最难理解的是那两张映射表的作用，理解了两张映射表，基本上也就理解了整套数据库的设计。而实现阶段，比较难理解的就是上面说到的模组<a href="http://docs.noahweb.net/ProjectA/checkuserpurview.html" target="_blank">checkuserpurview</a>了。理解该模组，需要联合数据库设计，actiongroup表中记录着用户组可以执行的权限，使用action字段和groupid字段进行查询，返回的数大于1，说明了用户所在的组拥有执行该动作的权限。</p>
<p align="left"><strong>附录</strong></p>
<blockquote>
<p align="left"><a href="http://www.noahweb.net/download/demo/news_mysql.zip" target="_blank">MYSQL版本权限管理系统源码下载</a></p>
<p align="left"><a href="http://www.noahweb.net/download/demo/news_sql.zip" target="_blank">MSSQL版本权限管理系统源码下载</a></p>
</blockquote>  <img src ="http://www.blogjava.net/zpq/aggbug/134321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zpq/" target="_blank">玉澍淋枫</a> 2007-08-03 20:11 <a href="http://www.blogjava.net/zpq/articles/134321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实现业务系统中的用户权限管理--设计篇</title><link>http://www.blogjava.net/zpq/articles/134320.html</link><dc:creator>玉澍淋枫</dc:creator><author>玉澍淋枫</author><pubDate>Fri, 03 Aug 2007 12:06:00 GMT</pubDate><guid>http://www.blogjava.net/zpq/articles/134320.html</guid><wfw:comment>http://www.blogjava.net/zpq/comments/134320.html</wfw:comment><comments>http://www.blogjava.net/zpq/articles/134320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zpq/comments/commentRss/134320.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zpq/services/trackbacks/134320.html</trackback:ping><description><![CDATA[<p><strong>实现业务系统中的用户权限管理--设计篇</strong></p>
<p><font size="2"><strong>　　</strong></font>B/S
系统中的权限比C/S中的更显的重要，C/S系统因为具有特殊的客户端，所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现，而
B/S中，浏览器是每一台计算机都已具备的，如果不建立一个完整的权限检测，那么一个&#8220;非法用户&#8221;很可能就能通过浏览器轻易访问到B/S系统中的所有功
能。因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测，让经过授权的用户可以正常合法的使用已授权功能，而对那些未经授权的&#8220;非法用户&#8221;
将会将他们彻底的&#8220;拒之门外&#8221;。下面就让我们一起了解一下如何设计可以满足大部分B/S系统中对用户功能权限控制的权限系统。</p>
<p>&nbsp;</p>
<p align="left"><strong>需求陈述</strong></p>
<ul>
    <li>
    <div align="left"><strong>不同职责的人员，对于系统操作的权限应该是不同的。</strong>优秀的业务系统，这是最基本的功能。</div>
    </li>
    <li>
    <div align="left"> <strong>可以对&#8220;组&#8221;进行权限分配</strong>。对于一个大企业的业务系统来说，如果要求管理员为其下员工逐一分配系统操作权限的话，是件耗时且不够方便的事情。所以，系统中就提出了对&#8220;组&#8221;进行操作的概念，将权限一致的人员编入同一组，然后对该组进行权限分配。</div>
    </li>
    <li>
    <div align="left"><strong>权限管理系统应该是可扩展的</strong>。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用，而不是每开发一套管理系统，就要针对权限管理部分进行重新开发。</div>
    </li>
    <li>
    <div align="left"><strong>满足业务系统中的功能权限。</strong>传统业务系统中，存在着两种权限管理，其一是功能权限的管理，而另外一种则是资源权限的管理，在不同系统之间，功能权限是可以重用的，而资源权限则不能。</div>
    </li>
</ul>
<p align="left"><strong>关于设计</strong></p>
<p align="left"><font size="2"><strong>　　</strong></font>借助NoahWeb的动作编程理念，在设计阶段，系统设计人员无须考虑程序结构的设计，而是从程序流程以及数据库结构开始入手。为了实现需求，数据库的设计可谓及其重要，无论是&#8220;组&#8221;操作的概念，还是整套权限管理系统的重用性，都在于数据库的设计。</p>
<p align="left">我们先来分析一下数据库结构：</p>
<p align="left"><font size="2"><strong>　　</strong></font>首先，action表（<strong>以下简称为&#8220;权限表&#8221;</strong>），gorupmanager表（<strong>以下简称为&#8220;管理组表&#8221;</strong>），以及master表（<strong>以下简称为&#8220;人员表&#8221;</strong>），是三张实体表，它们依次记录着&#8220;权限&#8221;的信息，&#8220;管理组&#8221;的信息和&#8220;人员&#8221;的信息。如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/16.gif" height="328" width="460"></p>
<p align="left"><font size="2"><strong>　　</strong></font>这三个表之间的关系是多对多的，一个权限可能同时属于多个管理组，一个管理组中也可能同时包含多个权限。同样的道理，一个人员可能同时属于多个管理组，而一个管理组中也可能同时包含多个人员。如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/1.gif" height="321" width="456"></p>
<p align="left"><font size="2"><strong>　　</strong></font>由于这三张表之间存在着多对多的关系，那么它们之间的交互，最好使用另外两张表来完成。而这两张表起着映射的作用，分别是&#8220;actiongroup&#8221;表<strong>（以下简称&#8220;权限映射表&#8221;）</strong>和&#8220;mastergroup&#8221;表<strong>（以下简称&#8220;人员映射表&#8221;）</strong>，前者映射了权限表与管理组表之间的交互。后者映射了人员表与管理组表之间的交互。如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/15.gif" height="318" width="637"></p>
<p align="left"><font size="2"><strong>　　</strong></font>另外，还需要一张表来控制系统运行时左侧菜单中的权限分栏，也就是&#8220;权限分栏表&#8221;，如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/17.gif" height="318" width="637"></p>
<p align="left"><font size="2"><strong>　　</strong></font>根据上面的分析，我们进行数据库结构设计，如下图：</p>
<p align="left">　　<a href="http://www.noahweb.net/mail/2/Project.htm#biao" target="_blank">点击这里查看权限管理系统数据表字段设计</a></p>
<p align="center"><img src="http://www.noahweb.net/mail/2/datebase.gif" height="320" width="624"></p>
<p align="left">&nbsp;</p>
<p align="left"><font size="2"><strong>　　</strong></font>为了能够进行良好的分析，我们将数据库结构图拆分开来，三张实体表的作用已经很清晰，现在我们来看一下两张映射表的作用。</p>
<p align="left"><strong>一 权限映射表</strong> 如下图：</p>
<p align="left"><font size="2"><strong>　　</strong></font>首先，我们来了解一下<strong>权限映射表</strong>与<strong>管理组表</strong>以及<strong>权限表</strong>之间的字段关联。</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/6.gif" height="159" width="457"></p>
<p align="left"><font size="2"><strong>　　</strong></font>看图中的红圈，先看gorupid字段相关联，这种关联方式在实际数据库中的表现如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/3.gif" height="152" width="534"></p>
<p align="left"><font size="2"><strong>　　</strong></font>如图中所示，<strong>管理组表</strong>中&#8220;超级管理员&#8221;的groupid为1，那么<strong>权限映射表</strong>中groupid为1的权限也就是&#8220;超级管理员&#8221;所拥有的权限。</p>
<p align="left"><font size="2"><strong>　　</strong></font>使用groupid字段关联，是为了查到一个管理组能够执行的权限有哪些。但这些权限的详细信息却是action字段关联所查询到的。</p>
<p align="left"><font size="2"><strong>　　</strong></font>action字段相关联在数据库中的表现如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/5.gif" height="154" width="540"></p>
<p align="left"><font size="2"><strong>　　</strong></font>通过这种关联，才查询到<strong>权限映射表</strong>之中那些权限的详细信息。综合起来，我们就知道了一个管理组可以执行的权限有哪些，以及这些权限的详细信息是什么。</p>
<p align="left"><font size="2"><strong>　　</strong></font>或许你会问，为什么不使用actionid字段相关联呢？因为：</p>
<ul>
    <li>
    <div align="left"><strong>权限表</strong>中的id字段在经过多次的数据库操作之后可能会发生更改。</div>
    </li>
    <li>
    <div align="left"><strong>权限映射表</strong>中仅仅记录着一个管理组可以执行的权限。</div>
    </li>
    <li>
    <div align="left">一旦<strong>权限表</strong>中的id更改，那么<strong>权限映射表</strong>中的记录也就更改了。</div>
    </li>
    <li>
    <div align="left">一个管理组可以执行的权限势必将出错，这是非常不希望的。</div>
    </li>
</ul>
<p align="left"><font size="2"><strong>　　</strong></font>考虑到上面的情况，所以应该使用action字段相关联，因为：</p>
<ul>
    <li>
    <div align="left">在<strong>权限表</strong>中，id可能发生变化，而action字段却是在任何情况下也不可能发生变化的。</div>
    </li>
    <li>
    <div align="left"><strong>权限映射表</strong>中记录的action字段也就不会变。</div>
    </li>
    <li>
    <div align="left">一个管理组可以执行的权限就不会出错了。</div>
    </li>
</ul>
<p align="left"><strong>二 人员映射表</strong> 如下图：</p>
<p align="left"><font size="2"><strong>　　</strong></font>我们来了解一下<strong>人员映射表</strong>与<strong>管理组表</strong>以及<strong>人员表</strong>之间的字段关联，如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/13.gif" height="324" width="442"></p>
<p align="left">&nbsp;</p>
<p align="left"><font size="2"><strong>　　</strong></font>看图中的红圈部分，先看groupid字段关联，这种关联方式在数据库中的表现如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/10.gif" height="109" width="437"></p>
<p align="left"><font size="2"><strong>　　</strong></font>如图，&#8220;超级管理员&#8221;组的groupid为1，我们再看<strong>人员映射表</strong>，admin属于超级管理员组，而administrator属于超级管理员组，同时也属于管理员组。</p>
<p align="left"><font size="2"><strong>　　</strong></font>使用这种关联方式，是为了查到一个管理组中的人员有谁。和上面一样，人员的详细信息是靠id字段（<strong>人员映射表</strong>中是masterid字段）关联查询到的。</p>
<p align="left"><font size="2"><strong>　　</strong></font>id字段（<strong>人员映射表</strong>中是masterid字段）关联表现在数据库中的形式如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/12.gif" height="108" width="526"></p>
<p align="left"><font size="2"><strong>　　</strong></font>一个人员可能同时属于多个&#8220;管理组&#8221;，如图中，administrator就同时属于两个&#8220;管理组&#8221;。所以，在<strong>人员映射表</strong>中关于administrator的记录就会是两条。</p>
<p align="left"><font size="2"><strong>　　</strong></font>这种关联方式才查询到管理组中人员的详细信息有哪些。综合起来，才可以知道一个管理组中的人员有谁，以及这个人员的详细信息。</p>
<p align="left"><font size="2"><strong>　　</strong></font>再结合上面谈到的<strong>权限表</strong>和<strong>权限映射表</strong>，就实现了需求中的&#8220;组&#8221;操作，如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/14.gif" height="323" width="636"></p>
<p align="left"><font size="2"><strong>　　</strong></font>其实，<strong>管理组表</strong>中仅仅记录着组的基本信息，如名称，组id等等。至于一个组中人员的详细信息，以及该组能够执行的权限的详细信息，都记录在<strong>人员表</strong>和<strong>权限表</strong>中。两张<strong>映射表</strong>才真正记录着一个组有哪些人员，能够执行哪些权限。通过两张映射表的衔接，三张实体表之间的交互才得以实现，<strong>从而完成了需求中提到的&#8220;组&#8221;操作</strong>。</p>
<p align="left"><font size="2"><strong>　　</strong></font>我们再来看一下<strong>权限分栏表</strong>与<strong>权限表</strong>之间的交互。这两张表之间的字段关联如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/19.gif" height="142" width="334"></p>
<p align="left"><font size="2"><strong>　　</strong></font>两张表使用了actioncolumnid字段相关联，这种关联方式在数据库中的表现如下图：</p>
<p align="center"><img src="http://www.noahweb.net/mail/2/18.gif" height="363" width="531"></p>
<p align="left"><font size="2"><strong>　　</strong></font>如图所示，通过这种关联方式，我们可以非常清晰的看到<strong>权限表</strong>中的权限属于哪个分栏。</p>
<p align="left"><font size="2"><strong>　　</strong></font>现在，数据库结构已经很清晰了，分配权限的功能以及&#8220;组&#8221;操作都已经实现。下面我们再来分析一下需求中提到的关于权限管理系统的重用性问题。</p>
<p align="left"><font size="2"><strong>　　</strong></font>为什么使用这种数据库设计方式搭建起来的系统可以重用呢？</p>
<ul>
    <li>
    <div align="left"><strong>三张实体表中记录着系统中的三个决定性元素。</strong>&#8220;权限&#8221;，&#8220;组&#8221;和&#8220;人&#8221;。而这三种元素可以任意添加，彼此之间不受影响。无论是那种类型的业务系统，这三个决定性元素是不会变的，也就意味着结构上不会变，而变的仅仅是数据。</div>
    </li>
    <li>
    <div align="left"><strong>两张映射表中记录着三个元素之间的关系。</strong>但这些关系完全是人为创建的，需要变化的时候，只是对数据库中的记录进行操作，无需改动结构。</div>
    </li>
    <li>
    <div align="left"><strong>权限分栏表中记录着系统使用时显示的分栏</strong>。无论是要添加分栏，修改分栏还是减少分栏，也只不过是操作记录而已。</div>
    </li>
</ul>
<p align="left"><font size="2"><strong>　　</strong></font>综上所述，这样设计数据库，系统是完全可以重用的，并且经受得住&#8220;变更&#8221;考验的。</p>
<p align="left"><strong>总结：</strong></p>
<p align="left"><font size="2"><strong>　　</strong></font>此套系统的重点在于，三张<strong>实体表</strong>牢牢地抓住了系统的核心成分，而两张映射表完美地映射出三张实体表之间的交互。其难点在于，理解映射表的工作，它记录着关系，并且实现了&#8220;组&#8221;操作的概念。而系统总体的设计是本着可以在不同的MIS系统中&#8220;重用&#8221;来满足不同系统的功能权限设置。</p>
<p align="left"><strong>附录：</strong></p>
<p align="center"><strong><a name="biao"></a>
</strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>下面我们来看看权限管理系统的数据库表设计，共分为六张表，如下图：</strong></p>
<blockquote>
<p align="left"><strong>action表：</strong></p>
</blockquote>
<p align="center"><strong><em><img src="http://www.noahweb.net/mail/2/datebase1.gif" height="119" width="502"></em></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>action表中记录着系统中所有的动作，以及动作相关描述。</strong></p>
<blockquote>
<p align="left"><strong>actioncolumn表：</strong></p>
</blockquote>
<p align="center"><strong><img src="http://www.noahweb.net/mail/2/datebase2.gif" height="75" width="459"></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>actioncolumn表中记录着动作的分栏，系统运行时，左侧菜单栏提供了几块不同的功能，每一块就是一个分栏，每添加一个分栏，该表中的记录就会增加一条,相对应的，左侧菜单栏中也会新增机一个栏。</strong></p>
<blockquote>
<p align="left"><strong>actiongroup表：</strong></p>
</blockquote>
<p align="center"><strong><img src="http://www.noahweb.net/mail/2/datebase3.gif" height="135" width="498"></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>actiongroup表记录着动作所在的组。</strong></p>
<blockquote>
<p align="left"><strong>groupmanager表：</strong></p>
</blockquote>
<p align="center"><strong><img src="http://www.noahweb.net/mail/2/datebase4.gif" height="135" width="405"></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>groupmanager表记录着管理组的相关信息，每添加一个管理组，这里的记录就会增加一条。</strong></p>
<blockquote>
<p align="left"><strong>mastergroup表：</strong></p>
</blockquote>
<p align="center"><strong><img src="http://www.noahweb.net/mail/2/datebase6.gif" height="150" width="444"></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>mastergroup表记录着管理员所在的管理组，由于一名管理员可能同同时属于多个组，所以该表中关于某一名管理员的记录可能有多条。</strong></p>
<blockquote>
<p align="left"><strong>master表：</strong></p>
</blockquote>
<p align="center"><strong><img src="http://www.noahweb.net/mail/2/datebase5.gif" height="300" width="409"></strong></p>
<p align="left"><strong><font size="2"><strong>　　</strong></font>master表记录着所有管理员的信息，每添加一个管理员，该表就会增加一条记录。</strong></p>
<strong> </strong><img src ="http://www.blogjava.net/zpq/aggbug/134320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zpq/" target="_blank">玉澍淋枫</a> 2007-08-03 20:06 <a href="http://www.blogjava.net/zpq/articles/134320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>