随笔 - 45  文章 - 129  trackbacks - 0
<2007年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

专注于C++ P2P STL GP OpenSource等
Google

常用链接

留言簿(10)

随笔分类

随笔档案

相册

朋友

搜索

  •  

最新评论

阅读排行榜

评论排行榜

引言

在开发Web应用系统中,用户管理是一个核心的问题。管理用户,必不可少要管理用户的联系方式。一般情况下,人们会建立一个专门的联系方式表,包含电话、EmailQQMSN等联系方式。不难发现,即便我们考虑得再周全,也无法罗列全部的联系方式,如手机、座机、小灵通、大灵通、skype等。那么,如何才能使用户能够自由添加各种联系方式而不会影响系统本身呢?让我们来探讨这个问题的解决。

 

一、直接在用户表中增加联系方式字段

我们最先在管理用户的时候,会直接在用户表后面添加联系方式,如下表:

 

用户名

单位

phone

email

张三

A公司

01012345678

aa@163.com

(表1

 

这在用户张三只有一个电话和一个Email地址的情况下,没有问题。但是,有一天,张三买了一个手机,并且把手机作为一种很重要的联系方式。开发人员很直观的想法就是在后面再加一个字段Mobile

 

用户名

单位

phone

email

Mobile

张三

A公司

01012345678

aa@163.com

13912345678

(表2

 

显而易见,这需要对用户表进行修改。这会为上层的程序带来麻烦。为了防止对用户表的修改,单独建立一个用户联系方式表是很自然的。

 

二、联系方式表与用户信息表分离

于是上面的用户表改变成下面两个表。

 

用户信息表

用户ID

用户名

单位

1

张三

A公司

2

李四

B公司

(表3

 

联系方式表

ID

phone

Email

Mobile

用户ID

1

01012345678

aa@163.com

13912345678

1

2

02033333333

bb@gmail.com

13688888888

2

(表4

 

这样一来,如果某一天又新增了一种联系方式,比如即时聊天工具QQMSN,我们无需改动用户信息表,只需要在联系方式表中增加相应字段就可以了。

是不是这样就已经令人满意了呢?

 

三、联系方式表扩展性问题

现在我们有一个新的用户名号王五,他既没有手机号,也没有Email,他只想留下QQ号作为联系方式。现在的表就变成这样:

 

用户信息表

用户ID

用户名

单位

1

张三

A公司

2

李四

B公司

3

王五

C公司

(表5

 

联系方式表

ID

phone

Email

Mobile

QQ

用户ID

1

01012345678

aa@163.com

13912345678

 

1

2

02033333333

bb@gmail.com

13688888888

 

2

3

 

 

 

232678

3

(表6

 

由于张三和李四输入信息时并没有QQ这一字段,所以张三、李四的联系方式记录的QQ字段的内容是空的。而王五的联系方式只有QQ这一字段有内容,其它几个字段都是空的。

现在,我们已经看出这种方式的问题了:

第一,         联系方式表中会一些字段的内容是空的,这会造成数据空间的浪费。

第二,         每增加一种联系方式,我们都需要在联系方式表中增加字段。这会使系统的维护变得非常复杂,还可能导致上层应用程序包括界面进行相应的修改。

 

于是我们便期望有一种更好的方法,能够解决联系方式扩充的问题,即:用户能够根据自己的需要添加联系方式,同时又不需要对数据库结构进行修改。

 

四、根据要素来构建联系方式表

好的,问题提出来了,我们就着手进行改进。先来进行一下理论的探讨:

联系方式是指联系一个人的手段或途径,联系方式最核心的要素是:方式+ 。即采用什么样的联系方式,这种联系方式的具体值是多少。如手机作为一种联系方式,值就是手机号码。QQ也可以作为一种联系方式,QQ号码就是联系方式的值。

 

从逻辑上讲,联系方式表的结构应该由其要素构成。即联系方式表的字段应该以方式和值作为最基本内容。

而我们上面建立的联系方式表,将phoneEmailMobileQQ等作为表的字段。而phoneEmail等都是联系方式的内容,并不是联系方式表的要素本身。这是导致联系方式表不灵活的根本原因。

那么,现在我们就真正按照联系方式表的要素来搭建结构,而将PhoneEmail等作为内容。

现在的联系方式表应该是这样:

 

ID

联系方式

1

Phone

13912345678

2

Email

aa@163.com

(表7

 

这样我们就可以随意添加联系方式到表中了。当然,由于联系方式都是与用户对应的,所以联系方式表中还应该包含一个用户ID字段,即:

 

ID

联系方式

用户ID

1

Phone

13912345678

1 (张三的用户ID

2

Email

aa@163.com

1

3

Phone

02033333333

2(李四的用户ID)

4

Email

bb@gmail.com

2

5

QQ

232678

3(王五的用户ID

(表8

 

这样,用户信息表与联系方式表就构成了一对多的关系。当然,这需要一种联系方式不是由两个人同时拥有,这也是与现实比较相符的。

 

五、让表结构更加优雅

前面的问题已经解决,我们是不是应该去喝庆功酒去了呢?

且慢,仔细看看最后的联系方式表(表8),有没有发现什么问题?在联系方式字段中,我们看到了两个Phone,两个Email。如果用户更多,看到的PhoneEmail可能还会更多。

在录入数据的时候,会不会出现两个Phone不一致的情况,如一个首字母大写,一个首字母小写?当然,你会回答,可以在录入数据时一律进行大小写转换。

好吧,那个问题就此打住。我还有另一个问题:如果我想把Phone改成SitePhone,应该怎么办?做一次遍历,然后进行替换?

更好的方式:将联系方式这个字段单独取出来,建立另一个表,不但能解决刚才提出的这个问题,而且会收到更好的效果,请看:

 

ID

联系方式

1

Phone

2

Email

3

QQ

(表9

 

ID

联系方式ID

用户ID

1

1

13912345678

1 (张三的用户ID

2

2

aa@163.com

1

3

1

02033333333

2(李四的用户ID)

4

2

bb@gmail.com

2

5

3

232678

3(王五的用户ID

(表10

 

这样做有什么好处呢?第一,联系方式PhoneEmailQQ等在数据库中只出现了一次,便于对这些联系方式进行修改,也有利于保持数据的一致性。第二、可以对每种联系方式附加一些属性,如联系方式的用户数,这种统计数字可以用来分析用户群体使用联系方式的特征,从而改进商业策略。

 

好了,最后我们把建立的最终表呈现在下面吧:

 

1、用户信息表

用户ID

用户名

单位

1

张三

A公司

2

李四

B公司

3

王五

C公司

(表11

 

2、联系方式表

ID

联系方式

数量

1

Phone

2

2

Email

2

3

QQ

1

(表12

 

3、用户联系信息管理表

ID

联系方式ID

用户ID

1

1

13912345678

1

2

2

aa@163.com

1

3

1

02033333333

2

4

2

bb@gmail.com

2

5

3

232678

3

(表13

 

六、题外话

就设计用户联系方式表这一简单的话题,我们一路走来。笔者认为,由表及里地思考对于我们设计可扩展的、易于维护的数据库系统非常有好处,可以为后续的管理、维护以及升级带来不少便利,省下不少精力和时间。我们的这种思考可以举一反三应用到选课数据库设计、用户权限管理数据库设计等方面。

当然,我们可以再上升到理论的层次:前面所做的工作事实上是对数据库设计的正规化形式的体现。如果对数据库进行正规化设计,请参阅我的另一篇笔记:http://blog.csdn.net/z365days/archive/2007/10/25/1842608.aspx

posted on 2007-10-30 10:26 CPP&&设计模式小屋 阅读(783) 评论(2)  编辑 收藏 引用 所属分类: 数据库

FeedBack:
# re: 建立动态可扩展的联系方式(转自博客http://blog.csdn.net/z365days/) 2007-10-30 14:47 蔡蔡
刚读研究生的时候,我在曾经的非常小型的项目里就用这种方式处理联系人信息,信息灵活的一个代价就是在展现层多写了许多许多的代码来对应扩展性,另外当时使用的是access数据库,没有存储过程,又在数据访问层写了很多的代码来保证数据完整性和正确性。现在回头看,在那么小的应用环境下也进行职责拆分多少有点过度设计的味道,虽然那个版本的通讯录从功能上和交互性上都比之前的版本好了许多,但是也因为涉及多表的一些问题,加上当年的稚嫩,开发和测试周期都延长了一些,呵呵  回复  更多评论
  
# re: 建立动态可扩展的联系方式(转自博客http://blog.csdn.net/z365days/) 2008-04-15 13:43 tzqdo@163.com
但是性能上的影响大不大呢?因为要查询至少三个表  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理