数据库该如何设计,一直以来都是一个仁者见仁智者见智的问题。
对于某一种数据库设计,并不能简单的用好与不好来区分。或许真的应了那句话,没有最好,只有最适合。讨论某种数据库设计的时候,应该在某种特定的需求环境下讨论。
下面来讨论一下在项目中经常碰到的用户的联系方式储存的问题。
我在这里套用之前网络上流行“普通——文艺——二逼”的分类方式来描述我下文中提及的三种数据库设计思路,并且通过查询数据(对数据增删改,三种设计要付出的代码成本都差不多)和数据库面临需求变动两个方面来思考这三种设计各有怎样的优劣。
普通青年:
或许我们都这样设计过数据库
学生表 tb_Student:
Name |
varchar(100) |
名字 |
Telphone |
varchar(200) |
联系电话 |
Email |
varchar(200) |
你懂的 |
Fax |
varchar(200) |
传真 |
这应该是最容易想到的一种思路,简单、明了。
比如说我要查询某个人的联系方式,那么我只用一条语句就能实现:
select
Name,Telphone,Email,Fax from
表 where
条件
在查询的时候,这种数据库设计十分清晰,没有任何思维的难度,没有任何逻辑的挑战。但是当面临需求变动的时候,那将会是一场灾难。
比如现在要新增一类用户:校长。那么我们要如何处理?
答案是:再加一张表 tb_Headmaster。
事实上,再加一张表其实修改并不大,因为我们完全不需要修改学生表的存储逻辑,换句话说,这种设计是遵循了开闭原则的
但如果学生要添加一种联系方式HomePhone的时候,灾难发生了
怎么办?
在tb_Student中加一列HomePhone?这意味着至少 要修改整个Model层(或者说DAL层),这种改动是十分巨大的,而且容易造成错误。
或者再建一张表tb_Student2,来储存HomePhone,然后以ID来关联两张表?按改动规模来说,这种改动相对简单而且不容易出错,但是在今后的维护中会增加逻辑成本。当你一而再再而三的以这样的方式来应对需求变动的时候,你的程序将变得不可理解。
文艺青年:
UserRole |
int |
对应用户类型(None = 0, Student = 1, Teacher = 2, Headmaster = 4) |
OwnerID |
int |
对应用户ID |
ContactMethod |
int |
联系方式(None = 0, Email = 1, HomePhone = 8, WorkPhone = 16,MobilePhone = 32,Fax=64) |
ContactInfo |
varchar(255) |
联系信息 |
这种是一个多对多关系。当我们要查询某个用户对应的联系方式的时候,那是一场逻辑上的浩劫:
select
ContactInfo from
表 where
UserRole=
某种用户类型 and
OwnerID=
某用户ID
这种写法是一次性取出某个用户所有的联系方式,包括Email,HomePhone,WorkPhone等,之后我们可以在程序中判断ContactMethod的类型,将具体的联系方式加以区分。你可以简单的想到用switch-case的写法,类似这样:
var
contact = 上面的SQL语句取出来的用户所有的联系方式;
foreach
(var
item in
contact)
{
switch
(item.ContactMethod)
{
case
ContactMethod.WorkPhone:
txtWorkPhone.Text
= item.ContactInfo;
break
;
case
ContactMethod.Email:
txtEmail.Text
= item.ContactInfo;
break
;
case
ContactMethod.Fax:
txtFax.Text
= item.ContactInfo;
break
;
case
ContactMethod.OtherPhone:
txtOtherPhone.Text
= item.ContactInfo;
break
;
case
ContactMethod.MobilePhone:
txtMobilePhone.Text
= item.ContactInfo;
break
;
}
}
当然你也可以尝试下面这种写法,我个人认为这种写法更优雅
var
contact = 上面的SQL语句取出来的用户所有的联系方式;
txtWorkPhone.Text
= (from
a in
contact
where
a.ContactMethod == ContactMethod.Work_Phone
select
a.ContactInfo).ToString();
//后面以此类推,你懂的
注意,请不要试图使用类似下面这类语句来查询某用户的联系方式:
select
ContactInfo from
表 where
UserRole=
某种用户类型 and
OwnerID=
某用户ID and
ContactMethod=
1
//
取出某用户的Email
select
ContactInfo from
表 where
UserRole=
某种用户类型 and
OwnerID=
某用户ID and
ContactMethod=
8
//
取出某用户的HomePhone
相信我,这种做法非常愚蠢:每当你要取出这个用户的一种联系方式,就要和数据库建立一次连接,打开/关闭一次数据库;这种做法代价是十分巨大的,即使有数据库连接池,即使有数据库缓存,都应该避免这种愚蠢的做法
唔,用了那么多的代码,终于查出了某个用户的联系信息了。反正我个人觉得这种设计方式在查询的时候,是逻辑上的浩劫。什么?你说你很享受?好吧,看来是我脑容量不够……
不过当我们面临需求变动的时候,那就非常愉快了。
什么,要加一类用户?简单,UserRole加一个枚举就好了。
什么,要加一种联系方式?ContactMethod加一个枚举就OK。
使用了这种表设计的时候,相信你会微笑着面对需求变动的
二逼青年
昨天和同事也探讨了下这个问题,按他的说法就是:哪个表要联系方式,我就扔个字段进去,存json
Contact |
varchar(8000) |
用于储存json |
举例来说,有这么一个用户:
ID:1 |
Name:张三 |
Telphone:1234 |
Email:123@123.com |
Fax:5678 |
那么数据库中就这样存:
[{"ID":1,"Name":"张三","Telphone":"1234","Email":"123@123.com","Fax":"5678"}]
当我听到这种设计思路的时候,虎躯微微一震:靠,这都行。按这种设计,我整张表都放进一个json里面一股脑的存进去就算了。不过震惊之后仔细想一想,其实这种设计也是有可取之处
首先,从查询来说,和普通青年一样,只需一句SQL:
select
Contact from
表 where
条件
查询之后,就可以通过json处理函数将想要的数据取出来,在此就不赘述了
那么当面临需求变动的时候会发生什么:
加一类用户的时候,要添加一张表。也是符合开闭原则,原有代码没有改动
加一种联系方式,只用存json的时候多存一点东西
不过这种设计如果要更新某条数据的话要稍微麻烦一点:先查询一条数据,重组json之后再Update
分享到:
相关推荐
数据库课程设计:长途汽车信息管理数据库设计 数据库课程设计:长途汽车信息管理数据库设计 数据库课程设计:长途汽车信息管理数据库设计 数据库课程设计:长途汽车信息管理数据库设计 数据库课程设计:长途汽车信息...
《自己动手设计数据库》提供的是数据库设计的一种概念性思路,因此与市面上众多的同类书籍相比,《自己动手设计数据库》有两个比较鲜明的特点。第一,作者采用简单易懂的语言,尽量清晰、全面地描述关系数据库设计的...
《自己动手设计数据库》主要讲述数据库的设计,讨论了如何建立表结构、确定主键、设置字段说明、建立表关系、确立业务规则、建立视图和各层次的数据完整性,以及如何避免不好的设计等问题。《自己动手设计数据库》...
软件数据库设计文档模板 software database design report document" 在软件开发项目中,数据库设计是非常重要的一步骤,...通过本文档,我们可以学习到数据库设计的每一个方面,并掌握数据库设计的要点和注意事项。
网吧管理系统数据库设计和相关文档网吧管理系统数据库设计和相关文档网吧管理系统数据库设计和相关文档网吧管理系统数据库设计和相关文档以及相关报表网吧管理系统数据库设计和相关文档网吧管理系统数据库设计和相关...
数据库设计文档.pdf 本文档是人资信息管理系统数据库设计文档,主要对软件后台数据库的概念模型设计...在数据库设计过程中,我们遵循了数据库的命名规则,设计了合理的数据库结构,确保了数据库的高效、安全和可靠性。
数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计数据库项目设计...
twitter数据库 twitter数据库设计 微博数据库设计
数据库课程设计数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库课程设计方案数据库...
数据库原理及应用课程设计报告---学校的工资管理系统的设计 里面包含了sql源码和课程设计报告,可供学习参考。高分课设。 一、课程设计目的及基本要求 数据库系统课程设计是为数据库原理及应用课程而独立开设的实践...
该文档通常包括以下几个部分:项目概况、数据库设计概述、逻辑设计、物理设计、数据模型、数据字典、索引设计、视图设计、存储过程设计、触发器设计、安全设计等。 数据库设计说明书的作用是: 1. 明确数据库的...
在设计数据库之前,需要对网上购物系统的需求进行分析。需求分析的目的是为了确定系统的功能和非功能需求,包括数据的存储和处理需求、安全性和性能要求等。 数据流图(DFD) 数据流图(DFD)是用来描述系统的数据...
数据库课程设计_大作业_超市管理系统设计与开发超市管理系统设计与开发_docx_ 数据库课程设计_大作业_学生选课管理系统_-2_docx 数据库课程设计_大作业_学生选课管理系统_docx_ 数据库课程设计_大作业_人事管理信息...
该资源提供了一些数据可课程设计实例,对数据库的期末课程设计很有帮助。这些实例涵盖了数据库设计、开发和实现的各个方面,包括需求分析、系统设计、数据库概念结构设计、数据库逻辑结构设计、数据库物理过程设计等...
标题“支付交易平台数据库设计文档”表明本文档详细介绍了构建银行支付交易平台时所需设计的数据库架构。数据库设计是信息技术领域中极为重要的一环,尤其是在金融行业,其准确性、完整性和安全性的要求尤为严格。本...
数据库设计详解 数据库设计是指在设计和开发...通过对NETCMS V1.0.0数据库详细设计的分析,我们可以了解数据库设计的基本概念、数据库结构设计、数据库性能优化、数据库安全设计和数据库备份和恢复等方面的知识点。
### 教务管理系统数据库设计详解 #### 一、引言 随着信息技术的发展,教育领域的信息化建设也变得日益重要。教务管理系统作为学校信息化建设的重要组成部分,对于提高学校的管理水平和服务质量具有重要意义。本篇...
在设计中,我们需要根据系统的需求来设计数据库的结构,包括确定实体、属性和关系。 实体分析 在设计数据库时,我们需要首先确定系统中的实体,包括考生、试题、成绩等。在本设计中,我们将考生、试题、成绩作为三...
数据库逻辑设计是指设计数据库的逻辑结构,包括数据路设计图和数据字典。数据路设计图是指数据库中数据流向的设计,而数据字典是指数据库中各个表的字段说明和数据类型。 在网上购物商城数据库设计中,主要包括以下...