日期:2014-05-17  浏览次数:20811 次

工作十年存疑——存储过程OR多层结构
本人涉足企业信息系统开发近十年有余,也接触了许多大大小小的信息系统开发的项目。对开发中究竟是使用将逻辑独立分层以构建三层(或多层)体系结构还是将逻辑写在存储过程中有仍有许多疑惑:

1、许多介绍企业信息系统类的书籍,上来就否定将数据写在存储过程中的做法,主张将所有的逻辑都写在“逻辑层”中,不到万不得已,绝不使用存储过程,说是存储过程虽然开发简便快捷,执行效率高,但会产生许多冗余代码,不便于维护和管理,仅适合于小型系统的开发,在大型系统中不能使用。存储过程产生冗余代码这一点我承认,由此带来的维护和管理问题也的确存在,但是因此就封杀掉了存储过程,我觉得过于片面和主观了,毕竟存储过程带来的好处远大于其带来的麻烦(现在Oracle、DB2等数据库已经提供了对Java存储过程的支持,相信在不久的将来,上述的问题将可迎刃而解)。

2、都说存储结构不适合大系统的开发,但多大的系统才算大系统呢?在我所接触到的信息系统项目中,甚至包括一些业务逻辑和表结构都相当复杂的项目,绝大部分都是可以使用二层架构实现的,而且相较于多层架构有着更高的开发和执行效率。除了一些大量并发查询的场合,将逻辑独立分层能够降低服务器负担(事实上,对分布式数据库而言,使用存储过程带来的这些负担是可以接受的),许多系统的开发完全可以快捷地通过二层架构实现需求。

3、在现实的开发过程中,要开发者掌握各种多层体系架构中的技术(例如ORM,各种设计模式等)是需要付出许多学习成本的,构建一个结构复杂的面向对象系统往往会导致开发失败,项目夭折。而使用存储过程编写的系统则相对要简单得多,并且能够胜任大部分信息系统的开发工作。项目中的程序员大多水平参差不齐,越短的学习周期意味着越高的项目开发成功概率。敏捷开发的思想在于快速构建系统原型,使用存储过程进行二层结构开发能够很好地与敏捷开发方法相契合。

4、说到面向对象,就要谈到数据抽象、封装,我觉得为什么不把数据库也视作一个对象呢?数据和操作(即存储过程)都封装在这个对象的内部,对外只提供相应的接口就行了,为什么还要单独地设立一个逻辑层,引入ORM,割裂这一对象的完整结构?

5、数据库本身在存储过程上做了那么多文章,提供了多种利于编写存储过程的工具和方式。耗费了高昂的价格购买的数据库却只想着去使用它的数据存储功能,此外还要购买ORM产品去解决数据持久层的问题,这一做法是不是值得商榷?

6、谈到移植成本,虽然将逻辑写在外部更容易移植,但正如前面所说的,使用多层体系结构,引入各种分层技术,域模型的方法势必会加大开发成本,为什么不将这些成本延迟到移植发生时才产生呢?再者说,移植也是一件概率非常小的事件,保持资金的流动性不是更好么? 
 
   以上只是鄙人的一些见解和感触,望能与大家相互讨论,并期待众大神能够不吝赐教!

------解决方案--------------------
确实,比如我原来的公司,是用java开发的系统,里面大部分的功能都是封装在java内的,程序把一部分经常访问的数据,缓存在应用服务器tomcat中,基本上所有的数据操作,都是通过ssh来实现的,比如定时任务,就是分装在java中的,而很少用数据库的作业来定时执行,其实大部分操作,无非就是从一堆表中经过计算,然后去修改其他表中的数据。

通过java来实现,有好处,比如系统的可移植性,比如,不管是sql server,还是oracle,程序都差不多,后台换成了其他数据库,基本上程序改动很小。

我发现很多程序员,包括一部分资深的程序员,他们对数据库只是达到了了解的程度,只是认为数据库吗,就是sql语句,sql语句嘛,无非就是增删改查,好像也没什么大的名堂,这是在每日早会的时候,我们的部门经理说的。

由于我不是java程序员,工作也主要是写sql语句,所以我在看问题的时候,更多从数据库的角度来看待问题,我觉得很多的功能,用数据库可能更合适一点,比如,上面说的定时任务,如果只是表中的数据计算,完全可以写个存储过程来实现,放到作业中,定时调用就可以了。

往往是系统性能出现了问题,才考虑会把一些计算,放到数据库端来实现。

还有就是规范化,比如写的存储过程完全没有注释,这让人根本没办法修改,而且很多存储过程都有严重的性能问题,开发的数据量很小,等系统运行一段时间后,数据量达到上亿的时候,就会突然暴露出来一堆的问题。

当有些重要的存储过程在运行时报错,我后来一看,这个存储过程就写的有问题,这些都严重缺乏测试。

所以我觉得,必须要加强培训,加强规范化,加强测试等等,这样才能提高系统的质量
------解决方案--------------------
我也和楼主一样在思考这个问题.
我们的业务逻辑也是封装在存储过程中的.这种模式很好用,性能好是不用说的,核心,复杂的业务逻辑都在存储过程中控制,这对视图层和控制层是是透明的.当然控制层会也根据配置动态地做一些通用的数据逻辑控制.当有业务变化时只需改存储过程就可以,而且是热修改,立即生效的.

当然,这样做也是有缺点的.
1.版本控制比较麻烦,目前没有比较好用的数据库版本管理工具,当然也不是说没有,我们现在有借助svn及开发的工具在进行版本控制.
2.迁移数据库.这是不行的,存储过程只能一直使用同一种数据库.不过,也可以把一些业务放在其他类型的数据库,再由存储过程调用,或直接由应用程序调用(比如说做成服务供调用).
3.数据库服务器成本高.业务逻辑全写在存储过程中无疑会需要更好的数据库服务器,而数据库服务器一般比web服务器要求更高,更昂贵.虽然这样可以省掉几台应用服务器,但成本还是较高的.
4.代码编辑和调试.在sql方面,编辑和调试工具明显跟不上时代.尤其是调试,基本只能靠print输出信息来调试

仅管有这么多缺点,我们还是在坚持这种模式,并且逐渐混合其他数据库或服务,不会所有业务全在数据库中现实,像队列,事务,消息,工作流,数据转移和同步等会改用其他的方式做.
------解决方案--------------------
1.存储过程也能配得上 开发简便快捷,真好笑。执行效率高,没有缓存结构的实时硬盘查询能高到哪里去?存储过程究竟带来了那些好处?我看好处就是:我只会存储过程啊!逻辑层拥有各种方便易用抽象手段,存储过程能行吗?迎刃而解 从何说起?
2.存储过程有着更高的开发和执行效率?和第一点重复,真好笑。分层能够降低服务器负担?你听谁说的?
3.需要付出许多学习成本,但是可以节省更多的开发时间,所谓磨刀不误砍柴工。导致开发失败,项目夭折,竟然能把责任退给面向对象,也只有楼主这样的SQLer才做得出。使用存储过程编写的系统则相对要简单得多?我从来没有看到过易读、易维护的存储过程,难道楼主是在说存储过程只能编写简单的系统?存储过程能够很好地与敏捷开发方法相契合?真弄不明白,存储过程与敏捷开发有什么强关联。
4.把数据库视作一个对象,那么接口是什么呢?SQL?如果把CPU视作一个对象,接口是指令流,是不是就不需要SQL了?
5.所谓术业有专攻,关系数据库只是一个专注于基于索引的数据持久化存取工具,逻辑处理不是它的重点,所以才会使用SQL这么简单的结构化语言。现在官方的、开源的好用的ORM一大堆,需要购买的是服务吧。
6.多层体系需要掌握某种一个框架,对于他们而言只会降低开发成本。对于SQLer而言,短期内加大开发成本是肯定的,因为需要学习新的技能。当然一般来说,用自己熟悉的技术做项目是应该的,但是把自己关在里面就...
这个存储过程提示prFindorder版费签免无效,如何改正呢