源自:http://www.cnblogs.com/lane_cn/
看了 Heroman的一篇文章,谈论 该不该在项目中使用存储过程代替SQL语句。 看后有一些感想,因为最近工作接触到一个系统,业务过程几乎完全是用存储过程实现的。随着系统的不断发展,新的需求逐渐难以支持。这个原因当然很复杂,即 使不使用存储过程,可能也有同样的问题。但是既然谈到具体技术上,就来看一下一个主要以存储过程实现的系统到底有哪些问题。
存储过程和嵌 入程序中的SQL哪个更好,要用一种合理的比较方式来比,不能拿写的好的存储过程和写的烂的程序比,当然也不能拿写的烂的存储过程和写的好的程序比。我们 先假设开发人员具有同样水平,项目组具有同样的组织协调能力,他们写出的存储过程和代码具有同样的质量,都已经根据产品的具体情况做出了最优的选择。
很 多人这样认为:存储过程运行在最靠近数据的地方,最大限度减少了业务处理的环节,因此具有最高的运行效率。对于一个独立的程序片断来说确实如此。但是当一 个软件规模逐渐增大,业务逻辑逐渐变得复杂以后,这一点差距已经不会对运行效率造成决定性的影响了。这时候,影响程序效率的因素变的更加复杂,比如:系统 对于并发任务的处理是否合理、是否具有分布式的能力、是否可以将常用的数据缓存……这些能力靠存储过程来实现是非常难的,甚至是不可能的。一旦采用了存储 过程,在程序漫长的生命周期中,要提高程序的运行效率就只有一个办法了:增加硬件投资。但是这个办法不一定有很好的效果,因为再好的硬件条件也无法弥补一 些根本的缺陷。
软件开发发展到现在,总的来说有个规律,就是要让开发者越来越少的考虑技术问题,越来越接近客户的业务思维。现代的软件开 发,已经越来越接近这样的方式:研究客户的需求,为业务建立模型,分析系统的外部和内部需求,以最接近业务模型的方式建立软件系统模型。这样的方式建立的 系统才能最好的满足客户的需要,同时也能较好的适应需求的发展。
如果采用存储过程作为建立业务层的形式,结果就是回到“排列需求——数据 库设计——界面设计——编码——测试”的道路上。这样当然是可以把系统做出来的。系统部署了,这只是他生命周期的开始,一切才刚开始。存储过程不仅实现了 当前的业务需求,也建立了一系列的API。在漫长维护过程中,维护人员在这些API的基础上实现新的需求、修改这些API的错误。如果发现某个API“似 乎”错了,或者不满足新的业务需求,没有人敢修改他们,最好的办法是:再加一个新的API。存储过程的数量越来越多,越来越难以命名——函数难命名不是编 码的问题,而是设计的问题。于是,在项目运行两年以后,还是难以形成一个优质稳定的业务开发平台,人们还在探究数据表、字段、VARCHAR500、 1403 data not found……
说到这里我也许应该得出结论,存储过程是不好的。可以这么说:用存储过程实现主要业务逻辑不是一个好办法。但是这个东西既然被创造出来,一定也有他适用的地方。
如 果我有这样的需求:数据库中有大量的实时运行数据,需要定期把这些数据进行简单的行列归整,放到另外一个数据库中做分析统计之用。在这种情况下我首选存储 过程。存储过程应该处理“数据”,而不要处理“业务”。并且在这种情况下存储过程极大的减少了IO消耗,真正的体现了他的效率优势。
评论
# re: 存储过程——天使还是魔鬼 2006-01-11 23:57 Microshaoft
系统对于并发任务的处理是否合理、是否具有分布式的能力、是否可以将常用的数据缓存……这些能力靠存储过程来实现是非常难的,甚至是不可能的
这里比较的是应用程序 SQL 和 存储过程!!!!!!!
一旦采用了存储过程,在程序漫长的生命周期中,要提高程序的运行效率就只有一个办法了:增加硬件投资。但是这个办法不一定有很好的效果,因为再好的硬件条件也无法弥补一些根本的缺陷。?????????????????? why?
存储过程不仅实现了当前的业务需求,也建立了一系列的API。在漫长维护过程中,维护人员在这些API的基础上实现新的需求、修改这些API的错 误。如果发现某个API“似乎”错了,或者不满足新的业务需求,没有人敢修改他们,最好的办法是:再加一个新的API。?????? 写在应用程序SQL里就没有此问题了???
性能 和 安全 要多考虑!
尤其在性能调优(业务逻辑不变)时,SP 修改很方便!应用程序根本不用动
不要走极端!消灭SP! 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 02:06 xiaotie
赞作者。
还有就是从可移植性这一角度来说,SP表现太差了。比如,偶2004年起放弃MS SQLServer,采用MySQL或PostgreSql。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 07:54 YngwieWang
我赞成SP处理数据,而不是业务。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 08:37 Orz
在能使用C#来创建存储过程的DotNet程序员眼里看来,你们这些还在讨论是用SP还是用SQL的人真的很好笑。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:12 zz堪
如果这篇文章的论点成立,那么C#来创建存储过程更不可用,更会影响性能 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:13 [天道酬勤]
没有绝对的对,也没有绝对的错.个人认为根据实际情况决定.既然存在就有它的必有性.从技术的角度讲各有自己的优缺点,从业务或商业的角度讲,在一个项目 里能用最快的周期和最少的后期维护成本,给项目创造最大的利润,哪种方式就是最合适的,(当然这里不一定是最好的) 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:16 jl
假如在一个很大的系统中,如果业务发生了点需求,对于sp来说只要稍微改一下就可以了,而程序则需要重新编译,测试……并且在部署的时候,你可以让整个系统都停吗?如果是一个很大的erp系统,一个企业正在使用中,这样停工仅仅是为了重新部署的后果你可以承担吗?
回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:23 風語者·疾風
上面有人说用C#写存储过程就怎么怎么。如果你真正用过CLR存储过程,你会发现那东西并不如想象中的好,甚至我觉得那玩意儿很鸡肋。
1、托管的存储过程无非就是在数据库上开辟的托管应用程序运行空间,然后通过一些接口去连接数据库执行语句,本身而言执行效率会更高。但是若你在 存储过程里去操作数据,并执行业务逻辑,那么你得先把所有数据获取到托管应用程序内存中,再进行处理,会占用更多的内存。因此这是不合理的。
2、CLR存储过程只支持返回DataReader和DataRecord两种数据方式,想拿它返回DataSet是不支持的。
3、有个挺麻烦的问题,CLR存储过程在VS里编写之后要编译,并部署到SQL Server上,做过修改就必须重新部署。而每次部署会导致之前对CLR存储过程做的权限设置丢失!!这个问题在实施中很严重。
综上所述,觉得CLR存储过程适用范围有限,倒是CLR方法倒更为实用。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:27 風語者·疾風
假如在一个很大的系统中,如果业务发生了点需求,对于sp来说只要稍微改一下就可以了,而程序则需要重新编译,测试……并且在部署的时候,你可以让整个系 统都停吗?如果是一个很大的erp系统,一个企业正在使用中,这样停工仅仅是为了重新部署的后果你可以承担吗?
这种论调是该被打烂屁股的!!
理由是,一个大型的ERP系统的生产环境允许你这样去直接修改存储过程?简直就是胡扯!乱弹!你能保证你修改就一定正确?不会对生产环境造成致命伤害?大型开发中,任何简单BUG都是必须有严格的缺陷管理流程,哪里能让你想改就改的?! 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:36 天生这样
虽然用SP可以减少网络交互,封装业务逻辑
但是把过量的业务处理放在SP中做,只会增加数据库服务器的负担
并不是明智的
不过数据库服务器可以集群,业务层的服务器也能集群
所以组合方式是很多的。
要看看具体项目来定夺。
回复
# re: 存储过程——天使还是魔鬼 2006-01-12 09:51 uGoer
SP和SQL Text各有春秋,应用场合不同也会有所侧重,我偏向于使用存储过程,不过不会把业务逻辑写到存储过程里,主要是取得数据然后结合缓存的方式来做业务处 理。 其实很多优秀的开源.NET 项目都是这样做的,比如DNN,CS等.微软也是一直推荐使用存储过程的. 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 10:22 kiler
假如在一个很大的系统中,如果业务发生了点需求,对于sp来说只要稍微改一下就可以了,而程序则需要重新编译,测试……并且在部署的时候,你可以让整个系 统都停吗?如果是一个很大的erp系统,一个企业正在使用中,这样停工仅仅是为了重新部署的后果你可以承担吗?
要是用户要求在数据库里面加字段,你可以只靠修改存储过程实现吗,如果使用存储过程仅仅是为了部署方便,就像你说的“只要稍微改一下就可以了”,那建议你用asp,更方便,无须编译。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 10:31 ξσ Dicky σξ
学习了 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 11:01 小陆
#在性能调优(业务逻辑不变)时,SP 修改很方便!应用程序根本不用动#
这里所说的“性能调优”,我猜想也就是加数据表索引,改改查询语句的条件。在“应用程序根本不用动”的情况下还能做什么其他的呢?
SP可以很方便的分表吗?再来一个多线程的并发查询?
你可以控制SP的变量生命周期吗?把常用的数据保存在里面以避免过于频繁的数据库读取。
我们可以比较容易判断一个模块在升级后是否保持向后兼容,只要判断接口的输入输出集合是否符合一定的规律。但是很难判断一个过程在升级后是否保持 向后兼容,这需要仔细检查其中的规则,有些规则是隐含的很深的。因此,升级一个复杂的SP只有两个办法:加上一个开关参数、或者写一个新的SP。
SP应该处理数据,而不是业务。我有理由痛恨SP,因为他给我带来了太多的痛苦,但是我不打算这么做。我不是要消灭SP,而是认为他应该做自己最擅长的事情。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 11:25 菩提树
"说到这里我也许应该得出结论,存储过程是不好的。可以这么说:用存储过程实现主要业务逻辑不是一个好办法。但是这个东西既然被创造出来,一定也有他适用的地方。"
这个我是同意的 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 11:58 Microshaoft
往往性能调优是要改代码的! 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 12:00 Microshaoft
再来一个多线程的并发查询?
并发调SQL语句!
并发调SP!
此时 SQL Text 与 SP 的地位有区别吗?
回复
# re: 存储过程——天使还是魔鬼 2006-01-12 12:35 New InterFace
使用不使用存储过程和业务
个人认为是没有必然的关系的。
这个只是使用者的熟练程度和水平问题
存储过程的使用本来就是为了更高的数据响应速度 减少系统消耗的。。。
很多人这样认为:存储过程运行在最靠近数据的地方,最大限度减少了业务处理的环节,因此具有最高的运行效率。对于一个独立的程序片断来说确实如 此。但是当一个软件规模逐渐增大,业务逻辑逐渐变得复杂以后,这一点差距已经不会对运行效率造成决定性的影响了。这时候,影响程序效率的因素变的更加复 杂,比如:系统对于并发任务的处理是否合理、是否具有分布式的能力、是否可以将常用的数据缓存……这些能力靠存储过程来实现是非常难的,甚至是不可能的。 一旦采用了存储过程,在程序漫长的生命周期中,要提高程序的运行效率就只有一个办法了:增加硬件投资。但是这个办法不一定有很好的效果,因为再好的硬件条 件也无法弥补一些根本的缺陷。
楼主的话 反而成了 使用存储过程会增加硬件负担。。。
汗颜之。。。
看来只有 仁者见仁智者见智 落。。。。
回复
# re: 存储过程——天使还是魔鬼 2006-01-12 13:36 小陆
可以到我这里参观一下,我们这里有两个主机,主要业务过程使用SP实现。现在其中一个忙死,另一个相对较闲,但是我们没有办法实现负载平衡。
一开始当然不是这样的,他们是很平衡的。但是一台主机上的业务不断的变化,新的任务越来越多,于是存储过程不断增加,增加……现在还有继续增加的趋势。原有负载分不开,新的需求继续使用SP来实现。有一个日报SP,执行一遍需要n*24小时。
最近在搞一个项目,把这两个主机上的业务重新分配。耗资数百万。
SP带来商机无限。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 14:33 鸿鹄
存储过程应该处理“数据”,而不要处理“业务”。
恕我愚钝,什么是“数据”,什么是“业务”呢? 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 14:36 komantian
人,总是吃过亏才知道经验的宝贵。
这篇文章很棒,至少面对这样一个SP密集的程序,最终还能在维护角度上撑下去,本身就是一个奇迹。
对于数据密集的业务,使用SP是一个自然而然的方法,然而当系统足够大,比如超过200SP时候,谁能保证修改一个SP而不影响其他SP?这样的环境,建立一个测试框架都是无比繁复的工作,那些数据就是用户的命,你敢动?
在运行期间重新部署程序固然讨厌,重新部署SP,更可怕。
同意作者观点:使用SP去处理数据,不要处理逻辑。逻辑最好在单个入口点集中维护,SP的特点恰恰让各种逻辑四处飞散。
如果已经有了这样的系统,忍受它吧,认真地呵护它,不要再产生新的SP了。 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 16:57 思无邪
结果就是回到“排列需求——数据库设计——界面设计——编码——测试”的道路上。这样当然是可以把系统做出来的。
深有体会,真是最好不要用存储过程了 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 17:43 leves
如果一个系统部署在web服务器和数据库服务器上,或者还有中间件服务器的时候,存储过程的优点就很明显了.
但是系统不断扩容修改后,存储过程的维护确实是个大问题! 回复
# re: 存储过程——天使还是魔鬼 2006-01-12 18:51 小陆
TO:鸿鹄
什么叫做操作数据,而不操作业务,我举个例子:
一个遍布全国的超市,有一个销售系统,这是一个实时运行的系统,同时也存储着大量的销售记录。这个企业还有一个经营分析系统。经营分析系统中的销售数据是从销售系统中得到的,但是他不关注具体的销售,他只关心销售量一定时期的变化情况。
于是产生这样的需要:“把销售管理系统中的营业额每日进行汇总保存,以便经营分析系统使用这些数据进行报表展现。”
描述这个需求的时候,只出现了一个业务概念:营业额。还有一个勉强算的上:时间。但是这个程序可以根本不关心他汇总是营业额,还是什么别的东西, 他根本不需要关注这个,他只把数据放到那里,至于这个数据如何解释,那是经营分析系统的任务。于是只剩下一个勉强算的上的业务概念:时间。
这个需求,我把他称作与业务无关的。当然不是绝对的没有关系,数据库设计毕竟是为业务需求服务的。但是这个关联已经非常小了。 回复
# re: 存储过程——天使还是魔鬼 2006-01-16 10:30 鸿鹄
TO 小陆
哦……,有点了解了。“数据”就是关心数据,而不是关心数据的解释,“业务”就是关心如何解释这些“数据”。是这样吗?
回复
# re: 存储过程——天使还是魔鬼 2006-01-20 00:47 Niels
我个人觉得是可以用存储过程处理业务的,用存储过程处理业务,相当于在数据之上增加了一个业务层,有什么不好?至于作者说的使用存储过程带来的维护方面的困难,用SQL Text一样存在,并且在代码中维护SQL比在存储过程中维护SQL肯定困难得多。
在我们项目组里,将代码中的SQL TEXT都称之为应编码,绝对不推荐。
我们前不久做得一个ERP项目让我充分体会到了存储过程给维护带来的方便。 回复
# re: 存储过程——天使还是魔鬼 2006-01-20 00:49 Niels
在我们项目组里,将代码中的SQL TEXT都称之为硬编码(Hard Code),绝对不推荐。 回复
# re: 存储过程——天使还是魔鬼 2006-01-20 20:16 无常
造成这个观点
“使用SP去处理数据,不要处理逻辑” 回复
# re: 存储过程——天使还是魔鬼 2006-01-26 17:56 proger
存储过程的好处是有时候不用改程序;
坏处是有时候除了改程序还要修改很多存储过程和触发器,而且它们不能被面向对象或者设计模式之类的模型封装起来,找起来很费劲。 回复
# re: 存储过程——天使还是魔鬼 2006-02-11 00:57 极地银狐.NET
存储过程,SQL语句,这都是客观的,看是什么人在用和用在什么情况下.
不能说存储过程就一定不好,SQL就一定好.
好比一把刀,你能说它是好还是不好吗?
这要看用它的人是职业杀手还是厨师了,以及在什么情况下使用. 回复
# re: 存储过程——天使还是魔鬼 2006-05-17 21:34 大悲天龙
一、用嵌入式SQL还是SP视项目组成员的组成而定。作者假设了一个条件:就是项目组的所有成员拥有相同的能力,之后的讨论其实都是在这个前提下。但是不 得不说,至少在我的周围,这种情况相当少见。我们的项目组开发部分的组成一般是由有经验的数据库程序员、有经验的Web程序员和有经验的测试人员构成的, 这种知识结构的差异几乎是必然的,所以有不少“专家”群落。这种前提下,SP无疑是一种很好的方法。数据库程序员只对自己的运行结果和效率负责、WEb程 序员只对自己的运行效率和界面负责,这样职责分明。而且,由于都是在某一个方面有丰富经验的人员,所以整体效率高、性能也比较值得信赖。
二、诚然,SP无法实现并行的数据调用,但同时,SP却省去了网络交互的时间,所以我觉得就算是面对业务逻辑,也有个SP和嵌入式SQL之间的 平衡问题。我觉得,当出现以下两种情况时不推荐使用SP:需要拼装SQL时、简单逻辑大数据量返回时。当然,还有一些书本上说的情况,就无用重复了吧。同 时,在以下情况,我强烈推荐使用SP:复杂Transaction配合小于1000个请求/秒。这可能和文章作者的观点向左。但我的实践是:如果一个 TRansaction中包含了对十来张中小型表的小数据量读取、判断、修改、添加和删除的时候,网络交互的开销会大大增加业务的处理时间,从而影响并发 能力和单笔处理速度,此时SP会更好。至于为什么是1000个请求/秒,实在是不好意思,因为我的系统最大负载时只是这个数,更高的并发请求我没有碰到 过,所以完全没有发言权。 回复
# re: 存储过程——天使还是魔鬼 2006-06-15 18:27 老狼
落后了,落后了,想不到存储过程上面有这么多争议。
俺用存储过程6年了,大部分是在MSSQL下,300个以上的存储过程的产品也开发、维护过,1000笔/s的业务也出现过,产品的后期维护量也 非常的大(的确是非常的大,不是因为本身bug,而是由于从事行业业务变化实在太快),虽然我们的开发过程很差,但还没有出现由于使用存储过程而导致的维 护困难,一直以来我们都坚持使用存储过程,非不得已不在程序里嵌入SQL语句,难道我们一直都错了?
实在是不知道为什么存储过程会给维护带来那么大的麻烦,看来的确是仁者见仁,智者见智了