项目感悟

  暑假阶段在J·Tu老师实验室做的新生网上报到系统已经完成了它今年的使命,这个时候再说这个项目的成功和失败已经失去意义了。现在所能做的,就是对这个项目中存在的一些硬伤进行总结归纳。由于我在该系统中仅仅是作为后台数据库的设计者和管理员,所以我也只有资格在这里面谈一些数据库设计上的错误。而且我也只是一个非一本院校里的很普通的一个学生,在这里谈经验也让那些大牛见笑了,权当是一个项目总结吧。希望这个系统的下一任设计者能够规避这些问题,同时也希望这篇文章能够对数据库初学者带来一点帮助。

  先把大致的基本表设计做个说明。由于是在学校,所以一定会存在大量的看上去没什么用的数据但是必须要有的数据。比如在这个项目中,我们就有学生注册表(新生进入学校以后才需要的信息,例如他在军训中穿的鞋子的尺码,军训服装的尺寸等等),学生基本信息表(类似于电子档案的东东,存了个人简历、家庭成员情况,主要社会关系等等),床位信息表,应缴费用表,银行卡号信息表(作为临时表存在,因为学校是先给出被录取学生的其他信息,然后才有银行卡信息,所以用该表的一个触发器将银行卡号更新到学生注册表中),问卷调查表等等。对了,后台数据库采用Oracle 10g Enterprise Edition

  在这些表中,最重要的就是应缴费用表和床位信息表。因为大家都知道现在大学的费用都不便宜,动不动就是四五千,多则上万。由于种种原因,现在的条件不允许我们让新生像网上购物一样,直接用银行卡在网上刷学费,而需要新生将需要交的费用存入学校和通知书一起寄出的银行卡中,然后学校将对应卡号需要划扣的金额提交给银行,银行划扣后将信息反馈给学校。在这个过程中,我就必须要保证这个表中的数据是绝对正确的。床位信息表之所以也会被列为最重要的表是因为学校通知书上说的很明确,床位先到先得。很多新生就是抱着网上报到就是选床位的心态来的,而家长也会想在经济能承受的情况下,选个好点的宿舍,比如要朝阳,或者不能顶楼(如果该班级在不同的楼层中都被分配了宿舍)。如果这个里面出现了问题,很多家长都会电话过来扯皮拉经。如果是因为我们这边(按照现代企业的观点,这个项目中有前台服务人员——就是接电话的,类似于10086人工服务台,然后就是我们这些负责技术的,在背后保障系统的正常运行,并按照学校要求提交所要的数据。本文中,我们这边指的是负责技术这一块的)出了问题,虽然学校最后出面能把问题解决,但是会有很大的压力,总之会让人很烦躁。

  废话就不多说了,开始说后台设计中出现的问题。

         1.出现了大量的数据冗余。在多个表中,有很多重复的数据,这个对数据库中数据的一致性带来了极大的隐患。在实际中,由于各个方面的原因,部分新生招进学校后,其专业会有一定的调整,有的是数据已经被导入了后台数据库以后过了几天突然招办发来一个通知说哪些学生要改专业。这样就会造成学号上的调整,而学费信息表中学费的信息是和班级相关的(学号中记载了班级信息,方便管理),学号变动,学费等相关费用就会随着一起变动。因为多个表中都有考生号和学号,所以最后的解决方案是将要调整的考生信息从库中所有表里删除,然后重建他的信息。

         2.环形关联。学过一点数据库的都知道,这个是基本表设计的大忌。虽然我一直在尽力规避这个问题,但是由于种种原因,迫使我不得不采用这个东西。加上前台代码的健壮性较差。在问题原因出来之前,我几乎天天都要去修改床位表和学生注册表中不匹配的信息(学生信息表中以学生为主键记录床位号同时床位号唯一,床位表中以床位号为主键记录考生号同时考生号唯一,刚开始经常发现两张表中的床位信息不一致)。这样会让系统出现一个致命bug,每天都会报NullPointerException,这是很危险的。

         3.床位编码。床位编码中包含了改床位所属班级信息,这本来是一个很好的创意。我们通过读床位编码就能很清楚选择了这个床位的考生他所属的学院、专业、班级。但是今年出了这种问题。宿管中心将床位分给了学院,学院让辅导员排床位,因为编排床位时不够仔细,将同一个床位给了不同的班级(及床位编码中的班级信息不同,但床位信息相同或者说是编码不同,但指的是同一个床位),表中的唯一性约束显然就无法检测到,两个考生选了同一个床位,如果他们的银行卡都已经划扣成功,那么事情的处理就会非常麻烦了,如果换的床位不好,那么总要有一个人吃亏。在涉及自身利益的时候,没几个人会想到“吃亏是福”这个词的。

         4.触发器过多。因为我觉得触发器这个东西太强大了,所以几乎每张表都被我加入了触发器来进行数据的一致性维护。几乎是能用触发器的地方我都用上了,却没有注意到触发器也会影响执行的效率。举个很明显的例子,系统运行前期(学校录取到的新生数据是一批批提交给我的),导入数据500条只需要2秒左右,后期导入3000条却用了大约47秒。中间我使用的PL/SQL Developer直接失去响应,让我着实纠结了一把。这件事情教育了我:不能太迷信触发器了。

         5.主外键关联。当我拿到所有数据时,我确实不好去定义主键和外键的关联。东西太散了,而且很多时候都要有一些因为人为因素造成的变动(例如学号变动,床位号变动这些主键键值的变动让我不敢随便的加外键)。这也是我主要使用触发器的原因。

         以上是我认为这个项目中出现的最主要的问题,虽然最后数据没有任何差错,但是也是耗费了我极大的精力去做的,所以在我看来,这个项目可以直接判定为一个失败的项目,我对整个项目的失败必须要承担70%以上的责任。下面再来谈谈这个项目中出现的问题。

1.我们这个团队中没有Leader,虽然老师能在其中协调,但是我觉得团队中没有Leader是一个项目失败的隐患,必须要有个强硬的组长。当问题发生时但得不到大家一个一致的解决方案时,由Leader直接选择一个,然后项目组成员无条件的服从。

         2.责任。其实这个和第一点相同,整体意思就是说在每个环节中,大家要把自己的责任搞清楚,一旦出错了以后,必须要提供一个改正错误的solution,而且是尽快提供,同时要尽快把错误的源头找到并解决。

         以上问题是我对这个项目做完以后的感悟,也是给我提个醒。以后不能犯类似的错误,同时也希望在下一个版本的新生网上预报到系统中不会再出现一样的问题了。

 

posted @ 2009-09-10 18:15  Derek_nr  阅读(516)  评论(0编辑  收藏  举报