存储过程中支持和反对业务逻辑的参数是什么?
反对存储过程:编程空间中的业务逻辑
我高度重视表达的力量,我发现SQL空间并不具备表达能力.使用您手头上最好的工具来完成最合适的任务.摆弄逻辑和高阶概念最好在最高级别完成.因此,存储和海量数据操作最好在服务器级别完成,可能在存储过程中完成.
但这取决于.如果您有多个应用程序与一个存储机制交互,并且您希望确保它保持其完整性和工作流,那么您应该将所有逻辑卸载到数据库服务器中.或者,准备好管理多个应用程序中的并发开发.
我完全反对它.其中一个最大的原因是Earino说的第一个原因 - 它生活在一个地方.您无法轻松地将其集成到源代码管理中.几乎不可能让两个开发人员同时处理存储过程.
我的另一个主要抱怨是SQL不太擅长表示复杂的逻辑.你没有范围的概念,代码往往被复制粘贴,因为重用代码的能力较低(而不是OO语言).
您必须让开发人员访问数据库才能在那里进行开发.在许多组织中,我曾在数据人员处于与开发者不同的世界中,具有不同的权限等.在这些情况下将开发人员排除在数据库之外会更难.
我是一个思想流派,只要有商业逻辑:
住在一个地方
在哪里正确记录
通过松散耦合的服务提供适当的访问
通过已发布的抽象界面
我不关心逻辑是存在于存储过程,J2EE中间层,剪辑专家系统中还是存在于任何地方.无论你在哪里存储我们的业务逻辑,"苦难保护法"都会保证有人会说这是错误的想法,因为组件/存储库X需要换掉技术/方法Y.
一些想法:请注意这是一个以Java为中心的响应,但它是我近期(过去10年)的大部分经历
(1)(大型)开发团队的并行开发.如果你的应用程序是非常复杂,每个开发人员不能建立DB的自己的私人版本(与出席链接/ REF数据的/ etc ...)这是很难有开发商所有工作在整个团队存储在共享DEVL DB中的同一组PL-SQL(例如)包是什么?然后你卡住(我的经验)在数据库中工作,无效的程序/代码与表的不匹配,因为人们做出改变......
作为一名Java架构师,我觉得它让每个开发者更容易有一个私人的JBoss例如在桌面上和自己的一套功能轻松地工作,以自己的节奏,而不影响其他所有人整合......这是我带来. ..
(2)持续集成工具集,虽然存在在DB世界上一些类似的"概念",我的经验告诉我说(我在这里选择了我现在最好的品种的收藏)的组合:
mvn - 构建系统
junit - 自动化单元测试
nexus - repo manager(管理工件的生命周期版本,快照和发布)
哈德森 - ci构建服务器
声纳 - 静态分析工具/代码覆盖率报告/更多
使用上述所有工具(免费工具)运行大型项目,可以通过一致/简便的方式将XP交付给大众,并对整个IT员工实施质量控制.Oracle/PL-SQL没有要匹配的工具集
(3)工具/库/等... Java可以访问其他平台无法触及的一组惊人的服务 - 一些是免费的,一些不是.甚至是基本的,比如log4j(是的,它们用于PL/SQL,但是它们......它几乎不一样)允许允许开发人员创建灵活可调的日志记录,可以即时更改(非常适合dubugging) .自动API文档(通过javadoc).自动化单元测试覆盖率报告.令人难以置信的IDE(Eclipse),集成了调试器/自动部署到应用服务器.用于与sun下的各种服务进行交互的API,用于执行ANYTHING的开源库以及每个供应商的100%支持
(4)重用服务.有人评论的是真的.如果您有重型数据驱动的业务规则, 那么您可以争辩说这些应该存在于数据库层中.为什么?防止中间层都必须复制该逻辑.
但对于不是数据驱动或足够复杂的业务规则,OO是更自然的选择,也可以这样说.如果您在数据库中粘贴所有业务逻辑,那么它们只能通过数据库使用.
如果您想在客户端或中间应用程序层中完成验证并保存到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提供了一种中间方式:服务拥有自己的数据.只有服务才能访问数据; 获取数据意味着通过服务.在这种情况下,可以将规则放在任何一个地方.
应用程序来来去去,但数据仍然存在.
不要在sprocs中存储业务逻辑的另一个原因 - 数据库的扩展能力有限.在您的数据库是您的瓶颈是非常常见的情况,这就是为什么尽可能多地加载数据库是个好主意.
我的几点意见:
赞成存储过程:
在项目生命的一段时间之后,在大多数情况下,瓶颈是数据库而不是Web服务器 - 并且存储过程要快得多
使用sql profiler与ORM生成的sql查询非常困难; 使用存储过程很容易
您可以立即部署存储过程的修复程序,而无需服务窗口
为了提高性能,优化存储过程比使用ORM代码更容易
您可能有许多应用程序使用相同的db/stored procs
任何复杂的数据场景都是对存储过程的投票
赞成申请/ ORM:
你可以使用代码存储库(存储过程仍然可以,但昂贵)
java/c#language是表达业务逻辑的更好工具
java/c#更容易调试(动态生成的ORM sql除外)
数据库引擎的独立性(但是项目不太可能将数据库更改为另一个)
ORM提供易于使用的数据模型
在我看来:对于大型项目 - 去存储过程,对于其他项目 - 应用程序/ ORM将正常工作.
在一天结束时,唯一重要的是数据库.
业务逻辑应该封装在一个地方.我们可以保证逻辑始终运行并始终如一地运行.使用涉及数据库上的实体的所有活动必须运行的类,我们可以保证所有验证都正确运行.这个代码有一个地方,项目上的任何开发人员都可以轻松打开这个类并查看逻辑(因为文档可以并且确实已经过时,代码是唯一可靠的文档形式).
这对存储过程很难.您可能有多个sproc处理相同的表.将多个sprocs链接在一起以便逻辑只驻留在一个中变得难以操作.这是一个打击.如何确定数据库中"实体X周围的所有业务规则是什么"?有趣的搜索成千上万的sprocs试图追踪到这一点.
第二个问题是您将业务逻辑与持久性机制联系起来.您可能不会将所有数据存储在同一个数据库中,或者某些数据可能存在于XML等中.开发人员很难这种类型的不一致.
如果逻辑仅驻留在数据库中,则很难执行验证.你真的打电话给sproc来验证你的数据输入表格上的每个字段吗?验证规则和业务逻辑是近亲.这个逻辑应该都在同一个地方执行!