从11月中旬以来一直在做教务系统,开始阶段是各个子系统独立开发,包括评教系统、选修课系统、考试系统三个子系统,这三个系统已经有原型,我们采用的都是原型开发,因为需求已经确定,研究了一段时间把用例图、类图等画了画,完成了大部分了,快该写代码了然后,老师说需要把这三个系统整合在一起,做一个教务系统,教务系统是一个平台,可以往里面扩充子系统,使得信息可以共享,避免信息孤岛的出现。
对于想要建立共享性、集成性高的系统即要设计一个结构紧密又灵活性好的共享数据库,下面一段很长的时间就是设计教务系统的数据库……
下面是我们数据库设计的过程中遇到的一些问题
1. 数据库表之间该不该多用主外键呢 ?
先说我们做的评教系统,单独从这一个系统角度考虑,建立我们自己的数据库表,我们多加一些主键无所谓,加多点主键还可以使得表结构严谨,数据一致性好,但是当我们再加入新的系统的时候,把选课系统也加入到这个系统中,那么评教系统中的表就需要从新设计里面的主外键,出现这样的情况是当初设计表结构时没有考虑到灵活性,单独从一个系统角度考虑,即过多使用主外键也会使得表结构过于紧密、灵活性差,在什么情况下使用还需多多考虑。
那主外键就不使用了吗?当然不是,既然主外键可以使得表一致性高、扩展性差,那我们可以避开缺点,使用优点,在需要扩展的地方尽量不使用主外键关系,而在要求扩展性不高的地使用主键外键,根据这一原则更改表结构
更改后的数据库设计,如下
新增了中间表(关系表)充当主外键的作用维持数据一致性,把基础表中的键关系移动到了基础表与关系表中,这看上去好像是降低了基础表与基础表之间的耦合度,给基础表解耦,这让我想起了中介者模式,通过一个中介类来给各个对象解耦,通过中介通信,而不是让各个类直接通信,举个例子:各个国家中国、美国、日本等有时并不直接交涉而不是通过联合国,给各个国家之间解耦,不管是在生活、学习中,设计模式的思想无处不在,值得学习。
2. 基础表与子系统表如何划分 ?
从每一个子系统方面考虑,子系统表无论放基础里还是放自己系统里都可以实现,其区别是放基础里面别的子系统可以使用,来共享信息,分表的时候按着信息是否需要共享来分表,如果这种信息不需要共享,那我们就没有必要往基础表里面放,如果放在基础表里面反而会增加基础表负担,增加数据库表冗余。
举个例子:例如TB_Student、TB_Teacher、TB_College、TB_Department等表,只要是学校里的系统,一般都会用到这些信息,很显然,这些表应该归为基础表,另外还有一些特殊关系表也应该规则基础表,如老师课程关系表等,这也是基础信息,这些信息不依附于某个子系统。
其中,也还有很多细节问题,不一一列举,下面是数据库设计一点点经验
我们设计数据库时可以遵循这样的设计原则:
(1) 数据库中表的个数越少越好。
形成了对客观世界的高度抽象,进行了系统的数据集成,防止了打补丁式的设计
(2) 表中组合主键的字段个数越少越好。
因为主键的作用,一是建主键索引,二是做为子表的外键,所以组合主键的字段个数少了,不仅节省了运行时间,而且节省了索引存储空间;
(3) 表中的字段个数越少越好。
减少数据冗余,一种方法是“列变行”,所谓“列变行”,就是将主表中的一部分内容拉出去,另外单独建一个子表。这样就防止了将子表中的字段拉入到主表中去,在主表中留下许多空余的字段。
(4) 降低范式,增加冗余, 少用触发器, 多用存储过程。
(5) 当计算非常复杂、而且记录条数非常巨大时,复杂计算要先在数据库外面。
(6) 发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的做法是,以该表主键PK的某个值为界线,将该表的记录水平分割为两个表。若发现某个表的字段太多,例如超过八十个,则垂直分割该表,将原来的一个表分解为两个表。
(7) 对数据库管理系统DBMS进行系统优化,即优化各种系统参数,如缓冲区个数。