专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »数据库 » 数据库设计技巧:浅谈数据库设计窍门技巧(下) »正文

数据库设计技巧:浅谈数据库设计窍门技巧(下)

来源: 发布时间:星期一, 2009年4月6日 浏览:0次 评论:0
="t18">   3、多用户及其权限管理设计
  开发数据库管理类软件Software不可能不考虑多用户和用户权限设置问题尽管目前市面上大、中型后台数据库系统软件Software都提供了多用户以及细至某个数据库内某张表权限设置功能我个人建议:套成熟数据库管理软件Software还是应该自行设计用户管理这块功能原因有 2:
  1.那些大、中型后台数据库系统软件Software所提供多用户及其权限设置都是针对数据库共有属性并不定能完全满足某些特例需求;
  2.不要过多依赖后台数据库系统软件Software某些特殊功能多种大、中型后台数据库系统软件Software的间并不完全兼容否则旦日后需要转换数据库平台或后台数据库系统软件Software版本升级的前架构设计很可能无法重用

  下面看看如何自行设计套比较灵活多用户管理模块即该数据库管理软件Software系统管理员可以自行添加新用户修改已有用户权限删除已有用户首先分析用户需求列出该数据库管理软件Software所有需要实现功能;然后根据联系对这些功能进行分类即把某类用户需使用功能归为类;最后开始建表:
  
功能表(Function_table)
名称     类型    约束条件   介绍说明
f_id   无重复   功能标识主键
f_name char(20) 不允许为空 功能名称不允许重复
f_desc char(50) 允许为空 功能描述

用户组表(User_group)
名称     类型    约束条件   介绍说明
group_id 无重复 用户组标识主键
group_name char(20) 不允许为空 用户组名称
group_power char(100) 不允许为空 用户组权限表内容为功能表f_id集合

用户表(User_table)
名称     类型    约束条件   介绍说明
user_id 无重复 用户标识主键
user_name char(20) 无重复 用户名
user_pwd char(20) 不允许为空 用户密码
user_type 不允许为空 所属用户组标识和User_group.group_id关联

  采用这种用户组架构设计当需要添加新用户时只需指定新用户所属用户组;当以后系统需要添加新功能或对旧有功能权限进行修改时只用操作功能表和用户组表记录原有用户功能即可相应随的变化当然这种架构设计把数据库管理软件Software功能判定移到了前台使得前台开发相对复杂但是当用户数较大(10人以上)或日后软件Software升级概率较大时这个代价是值得


   4、简洁批量m:n设计
  碰到m:n关系般都是建立3个表mnm:n但是m:n有时会遇到批量处理情况例如到图书馆借书般都是允许用户同时借阅n本书如果要求按批查询借阅记录即列出某个用户某次借阅所有书籍该如何设计呢?让我们建好必须3个表先:

书籍表(Book_table)
名称     类型    约束条件   介绍说明
book_id 无重复 书籍标识主键
book_no char(20) 无重复 书籍编号
book_name char(100) 不允许为空 书籍名称
……

借阅用户表(Renter_table)
名称     类型    约束条件   介绍说明
renter_id 无重复 用户标识主键
renter_name char(20) 不允许为空 用户姓名
……

借阅记录表(Rent_log)
名称     类型    约束条件   介绍说明
rent_id 无重复 借阅记录标识主键
r_id 不允许为空 用户标识和Renter_table.renter_id关联
b_id 不允许为空 书籍标识和Book_table.book_id关联
rent_date datetime 不允许为空 借阅时间
……

  为了实现按批查询借阅记录我们可以再建个表来保存批量借阅信息例如:

批量借阅表(Batch_rent)
名称     类型    约束条件   介绍说明
batch_id 无重复 批量借阅标识主键
batch_no 不允许为空 批量借阅编号批借阅batch_no相同
rent_id 不允许为空 借阅记录标识和Rent_log.rent_id关联
batch_date datetime 不允许为空 批量借阅时间

  这样设计好吗?我们来看看为了列出某个用户某次借阅所有书籍需要如何查询?首先检索批量借阅表(Batch_rent)把符合条件所有记录rent_id字段数据保存起来再用这些数据作为查询条件带入到借阅记录表(Rent_log)中去查询那么有没有什么办法改进呢?下面给出种简洁批量设计方案不需添加新表只需修改下借阅记录表(Rent_log)即可修改后记录表(Rent_log)如下:

借阅记录表(Rent_log)
名称     类型    约束条件   介绍说明
rent_id 无重复 借阅记录标识主键
r_id 不允许为空 用户标识和Renter_table.renter_id关联
b_id 不允许为空 书籍标识和Book_table.book_id关联
batch_no 不允许为空 批量借阅编号批借阅batch_no相同
rent_date datetime 不允许为空 借阅时间
……

  其中次借阅batch_no和该批第条入库rent_id相同举例:假设当前最大rent_id是64接着某用户次借阅了3本书则批量插入3条借阅记录batch_no都是65的后另外个用户租了套碟再插入出租记录rent_id是68采用这种设计查询批量借阅信息时只需使用条标准T_SQL嵌套查询即可当然这种设计不符合3NF但是和上面标准3NF设计比起来种更好呢?答案就不用我说了吧


   5、冗余数据取舍
  上篇“树型关系数据表”中保留了个冗余字段这里例子更进步——添加了个冗余表先看看例子:我原先所在公司为了解决员工工作餐和附近家小餐馆联系每天吃饭记账费用按人数平摊月底由公司现金结算每个人每个月工作餐费从工资中扣除当然每天吃饭人员和人数都不是固定而且由于每顿工作餐所点菜色区别每顿花费也不相同例如星期中餐5人花费40元晚餐2人花费20星期 2中餐6人花费36元晚餐3人花费18元为了方便计算每个人每个月工作餐费我写了个简陋就餐记账管理数据库里有3个表:

员工表(Clerk_table)
名称     类型    约束条件   介绍说明
clerk_id 无重复 员工标识主键
clerk_name char(10) 不允许为空 员工姓名

每餐总表(Eatdata1)
名称     类型    约束条件   介绍说明
totle_id 无重复 每餐总表标识主键
persons char(100) 不允许为空 就餐员工员工标识集合
eat_date datetime 不允许为空 就餐日期
eat_type char(1) 不允许为空 就餐类型用来区分中、晚餐
totle_price money 不允许为空 每餐总花费
persons_num 不允许为空 就餐人数

就餐计费细表(Eatdata2)
名称     类型    约束条件   介绍说明
id 无重复 就餐计费细表标识主键
t_id 不允许为空 每餐总表标识和Eatdata1.totle_id关联
c_id 不允许为空 员工标识标识和Clerk_table.clerk_id关联
price money 不允许为空 每人每餐花费

  其中就餐计费细表(Eatdata2)记录就是把每餐总表(Eatdata1)条记录按就餐员工平摊拆开是个不折不扣冗余表当然也可以把每餐总表(Eatdata1)部分字段合并到就餐计费细表(Eatdata2)中这样每餐总表(Eatdata1)就成了冗余表不过这样所设计出来就餐计费细表重复数据更多相比来说还是上面方案好些但是就是就餐计费细表(Eatdata2)这个冗余表在做每月每人餐费统计时候大大简化了编程复杂度只用类似这么条查询语句即可统计出每人每月寄餐次数和餐费总帐:

SELECT clerk_name AS personname,COUNT(c_id) as eattimes,SUM(price) AS ptprice FROM Eatdata2 JOIN Clerk_tabsle _disibledevent=>   想象如果不用这个冗余表每次统计每人每月餐费总帐时会多麻烦效率也够呛那么到底什么时候可以增加冗余数据呢?我认为有2个原则:

  1、用户整体需求当用户更多关注于对数据库规范标准记录按算法进行处理后再列出数据如果该算法可以直接利用后台数据库系统内嵌来完成此时可以适当增加冗余字段甚至冗余表来保存这些经过算法处理后数据要知道对于大批量数据查询修改或删除后台数据库系统效率远远高于我们自己编写代码
  2、简化开发复杂度现代软件Software开发实现同样功能思路方法有很多尽管不必要求员精通绝大部分开发工具和平台但是还是需要了解哪种思路方法搭配哪种开发工具更简洁效率更高冗余数据本质就是用空间换时间尤其是目前硬件发展远远高于软件Software所以适当冗余是可以接受不过我还是在最后再强调下:不要过多依赖平台和开发工具特性来简化开发这个度要是没把握好后期维护升级会栽大跟头

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: