众所周知,设计一个优秀站点或计算机应用系统,必须有强大,有效的数据库的支撑.
数据库的设计一般要符合三大范式,即 :第一范式(1NF):数据库表中的字段都是单一属性的,不可再分.第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段x → 非关键字段y [见上面一篇]http://blog.programfan.com/article.asp?id=10192
分析:一个短信系统包含:用户信息,好友信息,和短信信息.
1.用户信息包含:用户ID,用户名称,用户其他信息....
2.好友信息包含:好友ID,好友名称,其他信息....
3.短信<留言信息>包含:短信ID,短信发送者,短信接收者,短信标题,短信内容,发送时间,是否已读.....
回复ID,发送者,接收者,标题,内容,回复时间,是否已读......
二.尝试:只建立一个表.包含如上信息.数据表中信息无包含关系,符合第一范式[1NF].
假定短信发送表sendmsg[用户,接收用户,短信内容,用户信息,接收用户信息...]
存在如下决定关系: 1.用户----->用户信息.
2.接收用户-------->接收用户信息.
3.短信ID----->短信标题,短信内容.
组合关键字决定非关键字:<用户,接收用户,短信ID>-----<用户信息,接收用户信息,短信标题,内容>
显然不符合第二范式[2NF],同时这个信息系统表会出现如下问题.
1.数据冗余:一个用户发送了N条短信,用户信息就会出现N次,一条短信被回复了M次,原是短信就会出现M次.
2.更新异常:当发送短信用户修改或者更新原是短信,则所有回复短信都要修改或更新原是短信,否则会出现驴头不对马嘴的情况.
3.插入异常:无.
4.删除异常:假定用户需要删除短信,同时双方的信息都被删除.同时已经被回复的信息就无法找到根源.系统不完善.
从实效性和可用性上,显然以上方案不可行.
建立四个表:user,msg,remsg,friends.
其中:user<ID主键,name,day-birth,month-birth,year-birth,email,qq,phone,address,selfvalue...>
msg<ID主键,title,infor,time,sender,notread,receiver...>
remsg<ID主键,msg-id,title,infor,time,sender,notread,receiver...>
friends<ID主键,whose,friend-name,friend-id..>
三.以上方案解决了异常于冗余问题.但friends表不符合第三范式[3NF]whose-->friend-name--->friend-id.但这种设计更客观,在操作过程中减轻了再次查找操作,减轻了服务器负担.
结论:
1.满足范式要求的数据库设计是结构清晰的,同时可避免冗余和操作异常,但符合范式要求的数据库设计并不一定是最优的,在数据库中存在1:N关系这种情况时,合并导致的不合范式的要求反而更合理.
无论如何,我们在设计数据库的时候,一定要时刻考虑范式的要求.
2.对于M:N的关系<用户对发送信息,信息对回复信息>,不能将M一边或N一边合并到一边去,这样会导致不符合范式要求,但是,也是最重要的,并不会导致操作异常和数据冗余.
3.一切完整,无操作异常,无数据冗余,减轻操作,查询负荷的设计都时最优方案.
评论