转自 http://www.cnblogs.com/zyx_blog/articles/2365967.html
系统页面权限粒度控制设计
系统页面权限粒度控制设计
说明:
表说明
- Users 用户表
- Depts部门表
- Roles角色表
- Menus菜单表
- Pages系统页面
- Actions各个页面中的操作权限和菜单操作权限
- RelationUser_Role用户与角色的关系表
- RelationRole_Action 角色与操作的关系表
- RelationUser_Action 用户与操作的关系
- RelationDept_Action部门与操作的关系
权限业务
- 默认用户只能拥有角色,通过角色获得操作权限.
- 但是在实际应用中部门,用户都可以具备特殊的操作权限.
- 此设计即可实现用户通过角色,部门,本身获得操作权限.
解决方式
通过获取3张权限关系表中数据,最后合并权限,即是当前用户所具备的系统操作权限和菜单操作权限
图1
GUID在数据库系统的应用
What‘s GUID ? GUID 是个根据网络卡MAC Address 及时间等因素随机产生的 128 Bits(=16 Bytes) 数字, 因为 2 的128 次方是个极大的数目, 因此发生重复的机率非常非常.... 低 (乐观地说: 乐透中奖的机率远远高于 GUID 重复, 我们可以假设 "不可能" 发生)! 摘录几个网络上流传的例子来说明 GUID 如何地"不太可能" 发生重复: 一. The probability of an accidental match is (theoretically - and I use that term guardedly) the same as throwing a set of 128 pennies, and having them all land in the same heads/tails combination twice. 二. 如果一台机器每秒钟产生10,000,000 个GUID, 则可以保证(机率意义上) 3,240 年不会发生重复! 三. 全世界有60 亿人口, 每个人每秒分配10 亿个号码, 那么需要分配1800 亿年! 反正等到地球毁灭了都不会用完的! 把 GUID 以字符串形式表达就会像 "12345678-1234-1234-1234-123456789012" (4 Bits 代表一个字符, 则有32 个字符, 加上4 条短线共有36 个字符的长度)! The challenges of designing database. 在传统信息系统的数据库端普遍存在几个设计上的难题, 为了解决这些题目, 开发团队经常需要付出较高代价! 这些难题包括: 一. ID (在此指概指在资料表中用来代表资料唯一性的字段) 值是否允许变更(例如: 部门编号, 产品编号, .....) ? ID 字段总是被使用与其它资料表关联, 因此, 需要先判断关联是否已经存在, 以做为 ID 字段可否变更的依据! 当 ID 字段关联的对象数目过多时, 需要在判断上付出更多成本! 二. 由复合字段形成资料表关联时, 是否需要对更多字段进行变更前的判断或处理? 复合字段组成索引的典型之一是单据明细 (或称 "分录", 或指 Detail data, 其主索引可能由单据编号及明细序号(流水号) 组成)! 当某笔明细资料前方插入或是删除另一笔明细时, 原有的明细序号是否需要变更? 不变更时明细序号是否连号且不重复? 变更后是否会破坏原有与其它资料的关联? 三. 无 ID 或主索引字段的资料, 能否与其它资料建立关联? 在自然情况下有些资料并不需要 ID 字段 (或是 ID 字段值并无实质意义), 例如: 1. 每天例行发出的提醒信息可能并不需要 ID 值, 但是, 当使用者从清单中选择一笔资料时, 系统如何明确地找到被指定的提醒明细呢? 2. 展开MPS 是一个批次作业, 其过程中会有许多的记录临时被产生或是合并!在每一笔过渡记录产生时, 并不需要具有编码规则的 ID 字段, 但是在整合同料号同时段的生产需求时, 如何能够正确地标记已被合并的数据呢?归纳以上的难题, 我们可以发现需求的核心就是: 能否为数据库里的所有记录, 赋予一个: (1)简单, (2)独一无二, (3)不会改变的"身份识别"? How does GUID change the world ? GUID 的唯一性完全满足我们的需求, 因此, 我们可以一个 GUID 字段做为代理键, 以取代自然键 (通常为资料表中"ID" 字段, 或是复合字段组成的主要索引), 并化解实务上遭遇的问题: 一. GUID 隔离了自然键以及关联的资料表: 自然键是可以被检视的, 若自然键为ForeignKey 且有对应的关联资料, 为了保持资料的一致性, 自然键值不应被异动或删除! 这样的保护控制大都需要额外的程序代码去处理! 代理键通常并不具字面上的意涵(例如: GUID), 因此, 在检视资料时并不会显现该字段, 所以代理键在产生后, 该值并无机会发生改变! 以代理键替代自然键成为资料表关联的主角, 自然键相对地成为类似"备忘" 性质的字段! 由于代理键被隐藏而不会被变更, 不论自然键如何修改, 根源于代理键所形成的数据关联永远稳定地存在! 二. GUID 替代复合字段的自然主键: 当自然主键是由多个字段组合而成时, 要撰写资料关联的SQL command 就显得有点烦人! 运用 GUID 字段进行关联, 可以轻易地使 SQL 化繁为简!另外, 当自然键由复合字段组成时, 有更多字段被同时使用于资料关联, 相对地, 需要对字段组合进行更多判断或是限制变更! 这样的控制需要付出偏高的代价, 实务上, 也不尽然可以进行控制, 例如: 因为其它单据明细的增减, 会 "强迫" 部份单据明细自然键里的序号字段递增/ 递减! 若以 GUID 做为代理键担任资料表的关联角色, 单据明细的 "序号" 字段因不涉及关联, 即可依据实务上的需求被变更, 并不需要额外的判断或控制! 三. 无自然键的资料表由 GUID 代理主键的功能: 在无自然主键的资料表建立 GUID 代理键后, 每一笔记录即刻具备可供识别 "身份" 的信息! 即使后来因为需求变更而必须存取该资料表中特定的记录时, GUID 代理键的存在足以满足这类的变动 (类似 "防震" 效果)! |
The actual usage of GUID 一. 在多对多的关联里替代复合字段以简化对应: 如: 传票分录的立冲 (传票明细多对多立冲), 借还款的冲销 (多对多冲销), ..... 等, 可由 GUID 代理键进行关联, 即可依 GUID 合并后统计冲销金额! 二. 在临时产生的资料中提供精确的识别: 如: 有些复杂报表需要额外统计或运算, 当这些运算不需以程序代码循环处理, 即可以SQL command 直接在该报表的暂存数据表批次运算(其实多数报表均为如此)!当多人同时检视相同报表 (检视条件并不相同), 即可运用 GUID 做为该暂存资料表中的识别! 每个使用者每次检视报表即为一个 Task (TaskGUID), 报表运算后只回传 TaskGUID 相符的数据! 几种高阶的开发语言 (包括: .NET, VB, Delphi, PowerBuilder, ....) 均已包装或是实现呼叫 Windows API 以产生 GUID 字符串的方法了, 所以这个 GUID 值可以由程序代码自行产生!Microsoft SQLServer 也提供了取得 GUID 字符串的函式 NewID; 还有未公开的 Stored procedure: sp_MSforeachtable, 它可以对数据库中所有的资料表进行统一的操作!结合 sp_MSforeachtable 与 NewID, 我们可以在几秒钟内对所有资料表统一添加名为 "GUID" 的字段(实例如下), 开始让 GUID 做为资料搜寻或关联的根据! /* 先指定要添加 GUID 字段的数据库后, 直接执行下列语法 */ What‘s matter with GUID? 由于做为索引字段(不论是Clustered Index/ Nonclustered Index) 的GUID 长度为36 Bytes, 相较于其它的自然键或自动编号(整数) 均显得过长, 使得索引页可容纳的信息较少, 必须搜寻较多的索引页次才能查询所需要的结果, 因此, 各个网络讨论区对于 GUID 在效能方面的表现是颇有质疑的!不过, 数据库系统的效能包括许多因素, 包括: 系统设计理念, 资料表切割, 索引设定, SQL command 撰写, 内存配置, IO 设备, ..... 等 (排行愈前者影响愈大), 效能调整需要全面的协调与改善, GUID 不会是运行效能的瓶颈肇因!市场上已存在着全面运用 GUID 代理键的商用软件, 被中小企业广泛采用的 Microsoft.SharePoint 系统也是如此! 由于运用 GUID 做为代理键, 许多因为自然键直接关联的难题会因为 GUID 的隔离而被优雅地化解, 原自然键上的复杂控制均可省略, 资料表之间的关联变得单纯, 数据库系统的运作也更稳定! |
GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值。
2)使用 T-SQL
cmd.CommandText = "SELECT NewID()";
string rowID = (string) cmd.ExecuteScalar();
cmd.CommandText = "INSERT INTO Table(ID,...) VALUES(@ID,...)
cmd.Parameters.Add("@ID",SqlDbType.UniqueIdentifier).Value = new Guid(rowID);
cmd.ExecuteNoQuery();
3、GUID 的优缺点
- 同 IDENTITY 列相比,uniqueidentifier 列可以通过 NewID() 函数提前得知新增加的行 ID,为应用程序的后续处理提供了很大方便。
- 便于数据库移植,其它数据库中并不一定具有 IDENTITY 列,而 Guid 列可以作为字符型列转换到其它数据库中,同时将应用程序中产生的 GUID 值存入数据库,它不会对原有数据带来影响。
- 便于数据库初始化,如果应用程序要加载一些初始数据, IDENTITY 列的处理方式就比较麻烦,而 uniqueidentifier 列则无需任何处理,直接用 T-SQL 加载即可。
- 便于对某些对象或常量进行永久标识,如类的 ClassID,对象的实例标识,UDDI 中的联系人、服务接口、tModel标识定义等。
- GUID 值较长,不容易记忆和输入,而且这个值是随机、无顺序的,所以使用时要注意场合,最好不要尝试用它来作为你的电子邮件地址 J
- GUID 的值有 16 个字节,与其它那些诸如 4 字节的整数相比要相对大一些。这意味着如果在数据库中使用 uniqueidentifier 键,可能会带来两方面的消极影响:存储空间增大;索引时间较慢。
综合来说, GUID 的优点带来的便利远超出其缺点带来的影响,随着诸如 WebService 等系统互联与整合技术的不断发展,其唯一标识的特性使得其应用越来越广,在您的应用程序中也应考虑使用它了。