`
huozheleisi
  • 浏览: 1236810 次
文章分类
社区版块
存档分类
最新评论

我们该如何设计数据库(一)

 
阅读更多

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

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

 

 

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

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

 

普通青年:

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

学生表 tb_Student:

Name varchar(100) 名字
Telphone varchar(200) 联系电话
Email varchar(200) 你懂的
Fax varchar(200) 传真

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

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

select
 Name,Telphone,Email,Fax fromwhere
 条件


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

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

答案是:再加一张表 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 fromwhere
 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 fromwhere
 UserRole=
某种用户类型 and
 OwnerID=
某用户ID and
 ContactMethod=
1
    //
取出某用户的Email

select
 ContactInfo fromwhere
 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 fromwhere
 条件

查询之后,就可以通过json处理函数将想要的数据取出来,在此就不赘述了

 

那么当面临需求变动的时候会发生什么:

加一类用户的时候,要添加一张表。也是符合开闭原则,原有代码没有改动

加一种联系方式,只用存json的时候多存一点东西

 

不过这种设计如果要更新某条数据的话要稍微麻烦一点:先查询一条数据,重组json之后再Update

 

 

3
14
分享到:
评论
3 楼 char1st 2012-04-28  
2b 青年 mongodb
2 楼 什么向往 2012-04-28  
二逼青年的做法的确让人有点觉得:靠,这都行!!
1 楼 cloudmail 2012-04-28  
如果只用到name来查询的话,支持2b做法
总之,2b做法是最容易扩展的,但只能通过name来查询

相关推荐

    自己动手设计数据库

    《自己动手设计数据库》提供的是数据库设计的一种概念性思路,因此与市面上众多的同类书籍相比,《自己动手设计数据库》有两个比较鲜明的特点。第一,作者采用简单易懂的语言,尽量清晰、全面地描述关系数据库设计的...

    数据库表设计数据库表设计

    数据库表设计数据库表设计数据库表设计数据库表设计数据库表设计数据库表设计数据库表设计

    自己动手设计数据库.[美]Michael J.Hernandez(带详细书签) PDF 下载 高清 完整版

    《自己动手设计数据库》提供的是数据库设计的一种概念性思路,因此与市面上众多的同类书籍相比,《自己动手设计数据库》有两个比较鲜明的特点。第一,作者采用简单易懂的语言,尽量清晰、全面地描述关系数据库设计的...

    数据库系统原理实验五/大作业:数据库设计与应用开发大作业

    为某个部门或单位开发一个数据库应用系统,具体内容包括:对某个部门或单位业务和数据进行调查,系统分析,系统设计,数据库设计,数据库创建和数据加载,能够使用后台SQL语句编程实现所需功能,系统测试和分析,大...

    数据库设计指南 数据库设计

    如果把企业的数据比做生命所必需的血液,那么数据库的设计就是应用中最重要的一部分。有关数据 库设计的材料汗牛充栋,大学学位课程里也有专门的讲述。不过,就如我们反复强调的那样,再好的 老师也比不过经验的教诲...

    数据库课程设计----学校的工资管理系统的设计

    数据库原理及应用课程设计报告---学校的工资管理系统的设计 里面包含了sql源码和课程设计报告,可供学习参考。高分课设。 一、课程设计目的及基本要求 数据库系统课程设计是为数据库原理及应用课程而独立开设的实践...

    14-数据库课程设计任务书-某客运公司运输管理系统数据库设计.docx

    14-数据库课程设计任务书-某客运公司运输管理系统数据库设计.docx14-数据库课程设计任务书-某客运公司运输管理系统数据库设计.docx14-数据库课程设计任务书-某客运公司运输管理系统数据库设计.docx14-数据库课程设计...

    数据库设计--ER图

    数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据。 1 数据库设计的基本步骤: 2 概念结构设计 2.1 E-R模型基本符号 2.2 初步E-R图设计 2.3 ...

    数据库课程设计---某中学的排课管理系统的设计

    数据库系统课程设计是为数据库原理及应用课程而独立开设的实践性课程。数据库系统课程设计对于巩固数据库知识,加强学生的实际动手能力和提高学生综合素质十分必要。本课程分为系统分析、数据库设计两个阶段进行。...

    数据库设计指南 数据库设计实例

    如果把企业的数据比做生命所必需的血液,那么数据库的设计就是应用中最重要的一部分。有关数据 库设计的材料汗牛充栋,大学学位课程里也有专门的讲述。不过,就如我们反复强调的那样,再好的 老师也比不过经验的教诲...

    关系数据库设计

    数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。 数据库设计通常是在一个通用的DBMS支持下进行,...

    一卡通系统数据库设计

    基于oracle的一卡通系统的设计,包括系统的架构和主要的代码

    物联网数据库如何设计?iot数据库和传统数据库有什么区别?

    时序数据库的数据存储设计在典型的物联网场景中,往往有许多各类不同的终端设备,布署在不同的位置,去采集各种数据,比如某一生产区有5万个终端,每个终端每10秒发送一次数据。当程序挂掉重启时,可以从WAL文件中...

    设计数据库系统设计设计数据库系统设计设计数据库系统设计设计数据库系统设计

    数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据。 数据库设计的基本步骤: • 需求分析 • 概念结构设计 • 逻辑结构设计 • 物理结构设计 ...

    客户订购登记数据库设计

    题目:客户订购登记数据库设计 初始条件: 一个公司希望为其客户订购行为建立一个数据库。...3. 基于该数据库,最好实现一个或多个应用程序(自己确定功能),程序设计语言(工具)任选。这一项是选作,不作硬性要求。

    4数据库设计文档.doc

    "XX公司xx事业部 "文档编号" "版本"A1 "密级 "商密A" " "项目名称"Xxx系统...7 一、引言 编写目的 例如:本文档是xx系统概要设计文档的组成部分,编写数据库设计文档的目的是:明 确数据库的表名、字段名等数据信息,用

    设计一个大学教学数据库应用.pptx

    设计一个大学教学数据库应用.pptx

    软件开发过程中数据库设计部分详解

    1数据库设计概述 .. 2数据库概念设计 .. 3数据库逻辑结构设计 .. 4数据库物理设计 .. 5数据库的实施与维护 ..

    《数据库课程设计》-旅游管理系统设计报告+SqlServer.doc

    第一章 旅游管理系统概述 1 1.1社会背景 1 1.2技术背景 2 1.2.1数据库概述 2 1.2.2 Visual Basic概述 3 1.3 系统开发任务概述 3 第二章 旅游管理系统可行性研究及需求分析 4 2.1项目概述 4 2.1.1 系统目标 4 2.1.2 ...

    数据库课程设计----某商店进销存管理系统系统的设计

    数据库课程设计----某商店进销存管理系统系统的设计 里面包含了源码和课程设计报告,可供学习参考。高分课设。 一、课程设计目的及基本要求 数据库系统课程设计是为数据库原理及应用课程而独立开设的实践性课程。...

Global site tag (gtag.js) - Google Analytics