|
本帖最后由 todaynew 于 2013-8-29 17:22 编辑
有很多初学者在数据表设计时,经常犯的一个错误就是将不该重复的字段在很多表中重复。他们在设计之初的最原始的冲动是一定要将需要看到的信息反映到每个数据表中,表这样设计是可以方便看见数据了,但在编写表的数据增加、修改、删除时,立刻出现了数据同步的问题。所以就可以经常听到这样的问题:我该如何不追加重复的数据?这个问题出现的频次非常的高,大约每个月都会出现几次。所以这种问题有时令人厌烦。
那么该怎么样的说明这个问题的解决呢?我想用一个最近某个版友的问题来加以讨论。先看看下面的这个图:
这个图中有两个表一个叫做任务表,一个叫做任务进程表。对这两个表我们分两步来进行讨论,第一步我们暂且将这两个表看成必要的一对多的关系。站在这样一种观察的角度来评判的话,任务进程这个数据表中的工程名称、要求完成日期这两个字段就是冗余的了。为什么这样说呢?原因在于这两个字段在任务表中已经存在,可以通过同时存在于两个表中的文件编号(分别为主键和外键)联接两个数据表,并得到包含着两个字段的一个查询。通常可以这样去理解,但凡在数据表中存在一个外键,也就存在对外键指向的主表的全部字段引用的条件。
可以对这个问题从反向再深入得讨论一番。提出这个问题的版友实际上发了两个帖子,第一个帖子中问怎么能不追加重复的记录,我在他的帖子中反问:什么叫做不重复记录?(这个反问我对很多版友都做出过)。他回答我,三个字段一样就是重复。要判断三个字段的重复需要一个相对比较复杂的Where子句,当然也是可以写出来的,问题在于这是一个伪命题。因为如果不存在那两个冗余的字段的话,这个判断就简单很多。也就是说麻烦是自找的,而不是必要的。
我们回到问题的第二步讨论上来。这个问题真的需要一对多的两个数据表吗?我们仔细观察一下这两个数据表,可以发现这两个数据表实际上是一对一关系,而不是一对多关系。原因在于任务进程表中的字段相对于文件编号都只会出现一组值而不是多组值,至少我是这样理解的。假设我的理解是准确的,那么任务进程表的存在就失去意义了。这样一来就可以将任务进程表中的字段合并到任务表中了。这处理后立刻带来一个效果,也就是根本上消灭了重复记录的基本原因。
由此我们不难看出,数据表的设计中需要努力的做到无为而治,不应人为的制造问题和麻烦。
这个问题是不是还有可以讨论的地方呢?答案是肯定的。从字面上理解,所谓进程是与时间相关的一些列活动,所以进程表一般反映与时间相关的若干项工作或任务完成的情况。在目前我们看到的这个图中,可以发现有六个日期型的字段,这些字段就是反映不同工作环节上的进度的。对此类问题通常有两种解决方法。其一是在设计程序时,我们已经能够明确哪些工作节点,需要记录其工作进度,而且节点不会增减和变化,那么我们可以将这种进度的描述放在字段上来反映。其二是如果工作节点事先难以预计,或者变化可能比较大,或者要考虑程序的扩展性,那么就需要单独设计进度表来加以处理。这种情况下,一般进程表的字段为:进程ID(主键),文件表号(外键),工作环节,计划日期,实际完成日期,责任部门,责任人,备注等。
按照这个图提供的信息,如果我来设计的话,将会是这样的几个表:
部门表:部门ID(主键),部门名称
人员表:人员ID(主键),姓名,联系电话,部门ID(外键)
任务表:项目ID(主键),工程名称,工程地点,预算金额,工程周期,备注
进度表:进度ID(主键),任务节点,任务描述,计划开始日期,计划完成日期,实际开始日期,实际完成日期,部门ID,人员ID,备注,项目ID(外键)
进度表中的任务节点可以设计查阅,选组合框控件,行来源类型为值列表,行来源为:任务接受;施工进场;拆迁;三通一平;基础施工;主体施工;装修;交验;退场;资料归档。
|
|