说在前面
可能您会问,树的系列还差第三篇没有写呢,怎么就又说数据库设计了?因为如果写第三篇的话,那么就涉及到了权限,而权限里面又涉及到了人员,这些信息都是存放在表里面的,所以就只好先说数据库设计了。
(说到这里,我也感觉到了,以数据库为主的话,各方面的关联确实比较密切,不容易分割,如果使用面向对象的话,也许能够更清晰的分割开来吧。)
前提:这里讨论的还是以数据为主的项目,数据都需要保存在关系型数据库里的项目。
正文:
当您接手一个项目后,打开SQL Server 一看,靠,五、六百个表,晕倒。打开数据库的设计图一开,一大堆的表挤在一起,各种连线错综复杂的一团,这绝对可以和迷宫相媲美了。爬起来再晕倒。
您想改变这种情况,于是您选择了面向对象,希望面向对象能够解决这种乱糟糟的情况,我不知道您成功了没有。
而我的思路是:数据库的事情还是找自己人来解决吧,不要麻烦外人了。所以我想进行一点小小的“改革”—— 增加几个概念,从另一个角度来看表之间的关系。
【表关系的图】
【以人员管理为例的说明】
表组:就是一组表,一些相关的表组合在一起,组成一个组,共同表达一项事物。比如这里要说的人员管理,和人员比较密切的若干各表和在一起,组成了人员表组。类似的还有以后会说的组织机构、权限管理等。
表群:一个大模块需要的表、表组,组合在一起,就是一个表群。
相关表:有关联的表。
不相关表:没有直接关系的表。比如人员表和产品分类表。
主表、跟随表、边界表、描述表。
主表:主要的表,核心表,可以独立存在。比如这里的人员自然信息表。是一个表组的“代表”。
跟随表:跟着主表走的表,不能独立存在。比如这里的联系信息表、工作经历表等。由于跟随表只记录主表的ID,而只看ID是不知道到底是谁的信息,所以说不能独立存在。
边界表:就是承上启下的意思,用于多对多的表的连接。也是连接两个表组的表。比如这里的“人员——角色表”、“人员——组织结构表”。
描述表:描述一个具体情况的表,比如省份表、学历表、产品分类表等。也就是字典信息表。
命名习惯:我的命名习惯是加前缀。表名前面要加上大模块的前缀(或者表组的前缀),后面才是表名。因为在SQL Server 的企业管理器里面可以按照表名来排序,这样相关的表就会排在一起,看起来方便一些。
视图名的前面要加上视图的标识(前缀),我习惯加上“V_”来和表名相区分。
存储过程的前面最好也加上一个存储过程的标识(前缀),我习惯加上“Proc_”。
注意:存储过程最好不要使用“sp_”,“xp_”,“dt_”开头。因为系统提供的存储过程和扩展存储过程都是以这些开头的,在寻找存储过程的时候,如果是这些开头的话,那么会先到系统的存储过程里面去查找。另外,加这样的前缀也不容易和系统的存储过程相区分。
这样我们在总体设计的时候,只需要关注的“表组”(其实也就是“主表”)和表组之间的关系就可以了,描述表、边界表都可以忽略,而跟随表大多数也可忽略了,在需要的时候看一下就可以了。主表是一个表组的“代表”,所以一个表组里面只能有一个主表。
这样在打开设计图的时候,映入眼帘的就不是一大堆表的,而是几个(或者十几个)表组。如果是很大的项目的话,那么看到的是几个表群。只有当需要关注细节的时候才去看一个表组里的有哪些表,再进一步看细节的话,才去看表里面的字段。
(虽然现在面向对象很流行,但是我还是习惯先设计数据库,以数据库为中心,围绕数据库转。当然这样的话,就给自己做了一个限制,只能够做那些需要数据库的项目,不过这样的项目也有很多呀,够我做的了,呵呵。)
很多项目都需要有一个人员管理的模块,这个可以说是一个基础吧,无论是OA、CMS、ERP、企业定制等都是需要的,网站里也会有一个会员系统吧。所以我就从这个比较基础的开始吧。(请看上面的图)
人员管理,首先要有姓名、性别、出生日期等信息的表,我们把这个表叫做“人员自然信息”,这里的字段的特点就是“唯一”,一对一的,自然里的,基础的,基本的就放在这里面。这个也就是人员表组的主表。
有了自然信息后,需要有一个联系信息,这个表也是一对一的。固定电话、手机、QQ、MSN、Email等。这是一个跟随表,跟着主表(人员自然信息)走的表。
然后就是学习经历、工作经历等一对多的表。这些也都是跟随表。
最后是登陆账号。而“人员——角色表”、“人员——组织结构表”,这个就是“边界表”,就是联系多对多的一个表,他负责“联系”两方面的表。
这么多的表如何来关联呢,很简单都只用EmpID来关联。
您可能会问如果一个人有两个手机号码,而表里面只有一个手机号的字段,那么要如何解决方式呢?有两种方式:一是不管有多少手机号,都放在一个字段里面,用逗号来分割就可以了。另一个就是增加一个字段,分别叫做“手机号1”、“手机号2”。您可能会说这种方法都不合理,应该把联系方式表改成一对多的形式。我觉得改成一对多就更麻烦了。
总结:
一对一、一对多、多对多,主从表,这样的分析完全是由关系型数据库本身的特点来做的,一点业务逻辑都没有考虑进去。
而我的上面的方法是把业务逻辑“掺和”进来了,从业务逻辑的角度来分析数据结构,做划分、做分组。
我想,大家或多或少都是这么做的吧,我这里只是把这种方式给“挑明了”。欢迎大家的看法。