我们该如何设计数据库

发表于:2012-5-02 10:18

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:CrazyJinn    来源:51Testing软件测试网采编

  数据库该如何设计,一直以来都是一个仁者见仁智者见智的问题。

  对于某一种数据库设计,并不能简单的用好与不好来区分。或许真的应了那句话,没有最好,只有最适合。讨论某种数据库设计的时候,应该在某种特定的需求环境下讨论。

  下面来讨论一下在项目中经常碰到的用户的联系方式储存的问题。

  我在这里套用之前网络上流行“普通——文艺——二逼”的分类方式来描述我下文中提及的三种数据库设计思路,并且通过查询数据(对数据增删改,三种设计要付出的代码成本都差不多)和数据库面临需求变动两个方面来思考这三种设计各有怎样的优劣。

  普通青年:

  或许我们都这样设计过数据库

  学生表 tb_Student:

Namevarchar(100)名字
Telphonevarchar(200)联系电话
Emailvarchar(200)你懂的
Faxvarchar(200)传真

  这应该是最容易想到的一种思路,简单、明了。

  比如说我要查询某个人的联系方式,那么我只用一条语句就能实现:

select Name,Telphone,Email,Fax from 表 where 条件

  在查询的时候,这种数据库设计十分清晰,没有任何思维的难度,没有任何逻辑的挑战。但是当面临需求变动的时候,那将会是一场灾难。

  比如现在要新增一类用户:校长。那么我们要如何处理?

  答案是:再加一张表 tb_Headmaster。

  事实上,再加一张表其实修改并不大,因为我们完全不需要修改学生表的存储逻辑,换句话说,这种设计是遵循了开闭原则的。

  但如果学生要添加一种联系方式HomePhone的时候,灾难发生了,怎么办?

  在tb_Student中加一列HomePhone?这意味着至少要修改整个Model层(或者说DAL层),这种改动是十分巨大的,而且容易造成错误。

  或者再建一张表tb_Student2,来储存HomePhone,然后以ID来关联两张表?按改动规模来说,这种改动相对简单而且不容易出错,但是在今后的维护中会增加逻辑成本。当你一而再再而三的以这样的方式来应对需求变动的时候,你的程序将变得不可理解。

  文艺青年:

UserRoleint对应用户类型(None = 0, Student = 1, Teacher = 2, Headmaster = 4)
OwnerIDint对应用户ID
ContactMethodint联系方式(None = 0, Email = 1, HomePhone = 8, WorkPhone = 16,MobilePhone = 32,Fax=64)
ContactInfovarchar(255)联系信息

  这种是一个多对多关系。当我们要查询某个用户对应的联系方式的时候,那是一场逻辑上的浩劫:

select ContactInfo from 表 where UserRole=某种用户类型 and OwnerID=某用户ID

  这种写法是一次性取出某个用户所有的联系方式,包括Email,HomePhone,WorkPhone等,之后我们可以在程序中判断ContactMethod的类型,将具体的联系方式加以区分。你可以简单的想到用switch-case的写法,类似这样:

  1. var contact = 上面的SQL语句取出来的用户所有的联系方式;  
  2.             foreach (var item in contact)  
  3.             {  
  4.                 switch (item.ContactMethod)  
  5.                 {  
  6.                     case ContactMethod.WorkPhone:  
  7.                         txtWorkPhone.Text = item.ContactInfo;break;  
  8.                     case ContactMethod.Email:  
  9.                         txtEmail.Text = item.ContactInfo;  
  10.                         break;  
  11.                     case ContactMethod.Fax:  
  12.                         txtFax.Text = item.ContactInfo;  
  13.                         break;  
  14.                     case ContactMethod.OtherPhone:  
  15.                         txtOtherPhone.Text = item.ContactInfo;  
  16.                         break;  
  17.                     case ContactMethod.MobilePhone:  
  18.                         txtMobilePhone.Text = item.ContactInfo;  
  19.                         break;  
  20.                 }  
  21.             }

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号