如何支持和反对将业务逻辑存储在存储过程中?
如何支持和反对将业务逻辑存储在存储过程中?
反对存储过程:将业务逻辑放在编程空间中
我非常重视表达的能力,而且我认为SQL空间并不是很具有表现力。对于最合适的任务,请使用您手头上最好的工具。与逻辑和高阶概念摆弄最好是在最高级别上完成。因此,存储和大量数据操作最好在服务器层面上完成,可能是在存储过程中。
但这要看情况。如果您有多个应用程序与一个存储机制进行交互,并希望确保其维护完整性和工作流程,则应将所有逻辑卸载到数据库服务器中。否则,请准备管理多个应用程序的同时开发。
我完全反对它。其中最大的原因之一是earino所说的第一个原因——它存在于一个地方。你不能很容易地将其集成到源代码控制中。几乎不可能让两个开发人员同时在存储过程上工作。
我另一个主要抱怨是SQL不能很好地表示复杂的逻辑。你没有概念范围,代码往往被复制粘贴,因为重用代码的能力较低(与面向对象的语言相比)。
你必须给开发人员访问数据库来进行开发。在我工作过的许多组织中,数据人员和开发人员处于不同的世界,拥有不同的权限等。在这些情况下让开发人员不接触数据库会更难。
我认为只要业务逻辑:
我并不关心这些逻辑是存储过程、J2EE中间层、专家系统中的规则,还是其他任何地方。无论你将业务逻辑存储在哪里,“痛苦守恒定律”都会保证,总有人会说这是错误的想法,因为需要用技术/方法Y替换组件/存储库X。
一些想法:请注意,这是一个以Java为中心的回答,但它是我最近(过去10年)经验的大部分
(1) 大型团队的并行开发。如果您的应用程序足够复杂,以至于每个开发人员都不能设置自己的私有版本DB(带有相关链接/参考数据等),那么很难让整个团队所有开发人员同时在共享的DEVL DB中工作于相同的PL-SQL(例如)包集?那么你就陷入了(我的经验)与在DB中使用无效的过程/代码不匹配表格的困境,因为人们进行更改...
作为一名Java架构师,我认为让每个开发人员在自己的台式机上拥有私有的JBoss实例并轻松地处理自己的功能集,以及在自己的节奏下集成而不会影响其他人... 这就是...
(2) 持续集成工具集 虽然在DB世界中存在一些类似的“概念”,但我的经验告诉我,以下组合(我在此选择我当前最喜欢的免费工具):
使用上述所有免费工具运行大型项目可以为众人提供一种一致/简单的方式,并对整个IT员工实施质量控制。Oracle / PL-SQL没有与之匹配的工具集
(3) 工具/库等 Java可以访问其他平台无法触及的惊人服务——有些是免费的,有些不是。甚至基本的服务,如log4j(是的,他们也有PL/SQL,但请尽量避免...这不是几乎相同的),允许开发人员创建可灵活调整的记录,可以随时更改(非常适合调试)。自动API文档(通过javadoc)。自动化单元测试覆盖率报告。令人难以置信的IDE(Eclipse)具有集成调试器/自动部署到应用程序服务器。与每种类型的服务进行接口的API,开源库可以做任何事情,并得到每个供应商的100%支持
(4) 服务重复利用。有评论说过的是对的。如果您有重度数据驱动业务规则,那么可以认为这些规则应该存在于DB层中。为什么?为了防止中间层都需要复制该逻辑。
但对于非数据驱动或足够复杂以至于OO是更自然的选择的业务规则也可以同样说。如果您将所有业务逻辑都放在DB中,则只能通过DB访问它们。
retCode = validateSomeDate(date);
if (retCode == 1) then
evaluateIfCustomerGetsEmail(...)//probably more stored proc invocations here...
sendEmailMsg(....)
else if (retCode == 2) then
performOtherBizLogicStuf(...) //again, may need data, may not need data
triggerExternalsystemToDoSomething(...) //may not be accessible via PL/SQL
fi
我相信我们都见过像上面那样编写的系统,并不得不在凌晨2点调试它们。当业务逻辑分散在多个层级时,很难获得一个连贯的复杂流程的感觉,在某些情况下甚至无法维护。
"你不能很容易地将其集成到源代码控制中。" - 如果将创建存储过程的代码放入版本受控的脚本中,则该反对意见消失。如果您遵循Scott Ambler的敏捷数据库思想,那么这正是您应该做的。
并非所有开发人员都是优秀的数据建模者。我可以想到一些可怕的模式,这些模式是由认为略懂SQL的开发人员创建的,他们认为自己是数据库专家。我认为让开发人员与DBA和数据建模师合作具有很大的价值。
如果只有一个应用程序使用数据库,我会说业务逻辑可以出现在中间层。如果许多应用程序共享数据库,则将其放入数据库中可能更好。
SOA提供了一种中间方法:服务拥有其数据。只有服务才能访问数据;访问数据意味着通过服务进行。在这种情况下,规则可以放置在任何地方。
应用程序来来去去,但数据始终存在。
不将业务逻辑存储在存储过程中的另一个原因是数据库的扩展能力有限。很常见的情况是数据库成为瓶颈,因此尽可能减轻数据库的负载是个好主意。
以下是我的一些观察:
支持存储过程的优点:
在项目生命周期的后期,大多数情况下瓶颈是数据库而不是Web服务器-而存储过程要快得多
使用ORM生成的SQL查询进行SQL分析非常困难;而使用存储过程则非常容易
您可以立即部署存储过程修复,无需服务窗口
为了性能,优化存储过程比ORM代码更容易
您可能有很多应用程序使用相同的数据库/存储过程
任何复杂的数据场景都是存储过程的好处
支持应用程序/ORM的优点:
您可以使用代码仓库(使用存储过程仍然可能,但代价高昂)
Java / C#语言是表达业务逻辑的更好工具
Java / C#更容易调试(除了动态生成的ORM SQL)
独立于数据库引擎(然而这不太可能会有一个项目切换到另一个数据库引擎)
ORM提供易于使用的数据模型
在我看来:对于大型项目-选择存储过程,而对于其他项目-应用程序/ORM也可以很好地工作。
最终,唯一重要的是数据库。
+: SQL Server有时会优化代码
+: 您必须传递参数,这限制了SQL注入问题
-: 您的代码依赖于单个数据库(一些数据库甚至没有存储过程)
-: 要更改代码,您需要连接到数据库
-: 逻辑组织不好
个人而言,我反对使用它,但我曾经在一个非常繁忙的网站上使用过它。在MS SQL中使用存储过程带来了巨大的好处,但是一旦我实现了缓存,这些好处就不那么明显了。