由【超级传送带】谈系统中如何使用数据库
看过金同学的【超级传送带】这篇Post及其里面的Reply,我又要深有所感,于是有话不得不发了。对系统设计来说之前我也说过没有一定之规,不通的系统设计的前提和背景有所区别,那么设计的方式有可能南辕北辙。就算是围绕数据库,以数据为核心的系统也会因为设计的出发点不通而产生很多相反的看法。那么我还是首先设定本次讨论的前提:一个以数据库为存储手段,以数据为核心的应用程序,比如说一个电子商务系统(又比如NewEgg,不要误会,我不在NewEgg工作,只是有所了解)。
之前我提到过系统设计的取向问题,我们是先研究业务模型,先用OO的方法建模,然后再设计数据如何在数据库存储,还是反过来。这两种方式都不影响我们在系统中使用OO、使用设计模式、采用分层的设计。但是我们的讨论中最大的误会就经常因为设计的角度不同而产生。
一种方式是数据库参与到业务逻辑当中来,因为现在的数据库和基于关系模型的数据库查询语言具备强大的功能,通过关系模型可以将一些业务逻辑直接在数据库就实现了。在某些业务的逻辑计算中,关系模型具备一些天然的优势,而且当开发团队或者业务支撑团队中的Sql能力比较强的时候,大多会偏向用数据库来处理业务逻辑的方式。存储过程的优势在速度和业务逻辑的灵活性方面,Sql在数据库在很多工具的支持下也比较容易做性能调优,但是前提是必须要有足够强大的DBA,否则等于空谈。这类方式的缺点也很明显,一个是对人员要求的提高,其二是对职责分配的划分模糊,一个问题到底在数据库中解决还是在程序中解决,往往需要经过很多讨论,其三就是可维护性的问题,维护存储过程是一个很讲究的事情,我见过2万行的存储过程,要维护这样的东西简直可以称之为噩梦,特别是在人员更替的时候,经过多次转手后的存储过程可能会因为某个比较鳖足的DBA而搞砸。程序代码尚且如此,存储过程就更加令人郁闷。最后是和其他系统的交互问题,在一个业务逻辑的处理过程中涉及到第三方的诸如WebService之类的接口,是很难在存储过程中去调用的。最大的问题是会造成数据访问的代码沦为连接程序里的逻辑与存储过程里逻辑的接口,用DAL来作为接口会大大增加系统的耦合度,造成的后果可能就是,在某些时候业务逻辑修改后,DBA忙活半天,程序员也得跟着加班。
第二种方式就是彻底把数据库当作数据持久化的最终目的地,而业务逻辑就全部放在了代码中。之前的一篇Post里面,怪怪提到过数据库里也会包含业务逻辑的信息。对于这点其实是很正常的,在这种设计方式的时候,本来数据库的结构就是由业务模型分析出来,数据库所存储的都是业务数据,当然会包含业务逻辑的信息咯。其实我更加倾向于这种方式,关于这种方式的设计前面大家都讨论得比较多了我就不浪费笔墨在这里。不过纯粹的这类方式等于放弃了关系模型的强大业务计算能力。
接下来我们如何即避免第一种方式的缺点,但是有不要浪费数据库的能力呢?我想到一个办法是利用数据库将查询发布为WebService的功能,将存储过程发布成为一个WebService。然后在业务逻辑层去调用(纯粹吓吹 的,我没试过这种方式,就今晚篮球赢了后才想到的),这样避免了DAL与逻辑的耦合,又不会浪费强大的存储过程。
最后我们看了这两种方式后我们回过头来看看金同学的【超级传送带】的想法。金同学想通过【超级传送带】来实现从UI到数据库的一条龙式服务。这里我猜测金同学可能常常一个人孤军奋战,所以分层对他来说感觉就和脱了裤子放屁一样的麻烦。不过这样子横跨多个领域的组件(UI->逻辑->数据)对扩展性和灵活性的要求太高了,也许对金同学当前的业务来说可能还能胜任,但是对于金同学没有接触过的领域来说就显得不是那么的好用了,那么作为一个小众或者个人的玩具就显得不是那么有吸引力了,所谓独乐乐不如众乐乐嘛。那么金同学这种数据库就是逻辑的理论有点像用组件代替了第一种方式中的DBA的地位。那么我的观点也就不言而喻了。