古老的问题。在那里你应该把你的商务逻辑的,在数据库以存储程序(或包裹的),或在应用程序/中层?更重要的是,为什么?

假设数据库独立不是一个目标。

有帮助吗?

解决方案

在数据库中放入足够的业务逻辑,以确保数据的一致性和正确性。

但不要害怕必须在另一个级别复制一些逻辑以增强用户体验。

其他提示

在确定业务逻辑应该去哪里时,代码的可维护性始终是一个大问题。

集成的调试工具和功能更强大的IDE通常使维护中间层代码比存储过程中的相同代码更容易。除非有其他原因,否则您应该从中间层/应用程序中的业务逻辑开始,而不是在存储过程中。

但是,当您进行报告和数据挖掘/搜索时,存储过程通常可以更好地进行选择。这要归功于数据库聚合/过滤功能的强大功能以及您保持处理非常接近数据源的事实。但这可能不是大多数人认为的经典商业逻辑。

对于非常简单的情况,您可以将业务逻辑放在存储过程中。通常即使是简单的情况也会随着时间的推移变得复杂。以下是我没有将业务逻辑放在数据库中的原因:

将业务逻辑紧密地放在数据库中,将其与数据库的技术实现紧密结合在一起。更改表将导致您再次更改大量存储过程,从而导致大量额外错误和额外测试。

通常,UI依赖于业务逻辑来进行验证。将这些东西放在数据库中将导致数据库和UI之间的紧密耦合,或者在不同情况下重复这两者之间的验证逻辑。

很难让多个应用程序在同一个数据库上运行。一个应用程序的更改将导致其他应用程序中断。这很快就会变成维护噩梦。所以它并没有真正扩展。

更实际上,SQL不是一种以可理解的方式实现业务逻辑的好语言。 SQL非常适合基于集合的操作,但是它错过了“大规模编程”的构造。很难维护大量的存储过程。现代OO语言更适合并且更灵活。

这并不意味着您无法使用存储过程和视图。我认为在表和应用程序之间放置一层额外的存储过程和视图来解耦这两者是一个好主意。这样,您可以在不更改外部接口的情况下更改数据库的布局,从而允许您独立地重构数据库。

这取决于你,只要你是一致的

将其放入数据库层的一个很好的理由:如果您确信您的客户端永远不会更改其数据库后端。

将其放入应用程序层的一个很好的理由:如果您的应用程序针对多种持久性技术。

您还应该考虑核心竞争力。您的开发人员主要是应用程序层开发人员,还是主要是DBA类型?

虽然在应用程序层上拥有业务逻辑肯定有好处,但我想指出语言/框架似乎比数据库更频繁地更改。

我支持的一些系统在过去的10到15年中经历了以下用户界面:Oracle Forms / Visual Basic / Perl CGI / ASP / Java Servlet。没有改变的一件事 - 关系数据库和存储过程。

虽然没有一个正确的答案 - 这取决于有问题的项目,我会建议在“ Domain Driven Desig n”埃里克埃文斯。在这种方法中,业务逻辑在其自己的层中被隔离 - 域层 - 位于基础架构层之上 - 可能包括您的数据库代码,并位于应用层之下,后者将请求发送到域层实现并听取确认完成,有效推动申请。

通过这种方式,业务逻辑被捕获在一个模型中,可以与那些除了技术问题之外理解业务的人讨论,并且应该更容易隔离业务规则本身的变化,技术实现问题,以及与业务(域)模型交互的应用程序流。

如果你有机会我推荐阅读上面的书,因为它非常擅长解释这个纯粹的理想如何在真实代码和项目的现实世界中实际近似。

在这种情况下,提问者排除作为考虑因素的数据库独立性是将逻辑排除在数据库之外的最强有力的论据。数据库独立性的最有力论据是能够将软件销售给拥有自己的数据库后端优先权的公司。

因此,我认为将数据库中的存储过程仅作为商业过程而不是技术过程的主要论点。可能存在技术原因,但也有技术原因可以将其保留在那里 - 性能,完整性以及允许多个应用程序使用相同API的能力。

是否使用SP也会受到您要使用的数据库的强烈影响。如果您不考虑数据库独立性,那么您将使用T-SQL或使用PL / SQL获得非常不同的体验。

如果您使用Oracle开发应用程序,那么PL / SQL作为一种语言显然是一种选择。它与数据紧密耦合,在每次重复中都不断改进,任何体面的开发工具都会将PL / SQL开发与CVS或Subversion或其他一些整合。

Oracle的基于Web的Application Express开发环境甚至可以使用PL / SQL 100%构建。

任何影响数据完整性的内容都必须放在数据库级别。除了用户界面之外的其他事情通常是将数据放入,更新或删除数据库中的数据,包括导入,批量更新以更改定价方案,热修复等。如果您需要确保始终遵循规则,请将逻辑置于默认值中和触发器。

这并不是说在用户界面中也不是一个好主意(为什么要发送数据库不会接受的信息),但忽略数据库中的这些东西就是为了惹恼灾难

如果您需要数据库独立性,您可能希望将所有业务逻辑放在应用程序层中,因为应用程序层中的可用标准比数据库层可用的标准更为普遍。

但是,如果数据库独立性不是第一因素,并且团队的技能组合包含强大的数据库技能,那么将业务逻辑放在数据库中可能是最佳解决方案。您可以让您的应用程序人员执行特定于应用程序的事情,并让您的数据库人员确保所有查询都飞行。

当然,能够将SQL语句放在一起并具有“强大的数据库技能”之间存在很大差异。 - 如果你的团队比前者更接近前者,那么使用这个世界的一个Hibernates将逻辑放在应用程序中(或者改变你的团队!)。

根据我的经验,在企业环境中,您将拥有该领域的单一目标数据库和技能 - 在这种情况下,您可以将所有内容都放在数据库中。如果您从事软件销售业务,那么数据库许可证成本将使数据库独立性成为最重要的因素,您将在应用程序层中实现所有功能。

希望有所帮助。

现在可以提交subversion存储的proc代码并使用良好的工具支持调试此代码。

如果使用组合sql语句的存储过程,则可以减少应用程序与数据库之间的数据流量,并减少数据库调用次数并获得较大的性能提升。

一旦我们开始使用C#构建,我们决定不使用存储过程,但现在我们正在将越来越多的代码移动到存储过程。特别是批量处理。

但是,不要使用触发器,使用存储过程或更好的包。触发确实会降低可维护性。

将代码放在应用程序层中将导致数据库独立的应用程序。

出于性能原因,有时最好使用存储过程。

它(照例)取决于应用要求。

数据库中唯一存在的就是数据。

存储过程是维护的噩梦。它们不是数据,不属于数据库。开发人员和DBA之间的无休止协调只不过是组织摩擦。

很难对存储过程保持良好的版本控制。数据库外部的代码非常容易安装 - 当您认为版本错误时,您只需执行SVN UP(可能是安装)并将应用程序恢复到已知状态。您有应用程序的环境变量,目录链接和许多环境控制。

通过简单的 PATH 操作,您可以使用适用于不同情况的变体软件(培训,测试,QA,生产,客户特定的增强等等)。

然而,数据库中的代码更难管理。没有合适的环境 - 没有“PATH”,目录链接或其他环境变量 - 提供对正在使用的软件的任何可用控制;你有一套永久的,全球范围内的应用软件,它固定在数据库中,与数据相结合。

触发器更糟糕。它们既是维护也是调试的噩梦。我看不出他们解决了什么问题;它们似乎是一种解决设计糟糕的应用程序的方法,在这种应用程序中,有人无法正确使用可用的类(或函数库)。

虽然有些人发现性能参数引人注目,但我仍然没有看到足够的基准数据来说服我存储过程都那么快。每个人都有一个轶事,但没有人有并排的代码,算法或多或少相同。

[在我看过的例子中,旧的应用程序是一个设计糟糕的混乱;在编写存储过程时,应用程序被重新构建。我认为设计变更对平台变化的影响更大。]

业务逻辑应该放在应用/中间层次作为第一选择。这样,它可以表的形式域模型,被放源的控制,可以分割或相结合与相关代码(重组),等等。它还提供了一些数据库的供应商的独立性。

面向对象的语文也是更表现于存储程序,允许你更好的和更容易地描述了在码应该是什么情况发生。

只有很好的理由地方代码存储程序是:如果这样做会产生重大的和必要的性能受益,或者如果同一商业代码需要执行通过多种平台(Java,C#PHP)。即使在使用多个平台中,有替代品,如网络的服务可能更适合于共享的功能。

根据我的经验,答案取决于一系列价值观,通常取决于贵组织的技能所在。

DBMS是一种非常强大的野兽,这意味着适当或不恰当的治疗会带来巨大的好处或巨大的危险。可悲的是,在太多的组织中,主要关注编程人员; dbms技能,尤其是查询开发技能(与管理相对)被忽略了。由于评估dbms技能的能力也可能缺失,这进一步加剧了这一点。

并且很少有程序员能够充分理解他们对数据库不了解的内容。

因此,次优概念的流行,如Active Records和LINQ(引入一些明显的偏见)。但它们可能是这些组织的最佳答案。

但是,请注意,高度规模的组织倾向于更加关注数据存储的有效使用。

这个问题没有独立的正确答案。这取决于您的应用程序的要求,开发人员的偏好和技能,以及月亮的阶段。

业务逻辑将放在应用程序层而不是数据库中。 原因是数据库存储过程始终依赖于您使用的数据库产品。这打破了三层模型的优势之一。除非为此数据库产品提供额外的存储过程,否则无法轻松更改为其他数据库。 另一方面,有时,将逻辑放入存储过程以进行性能优化是有意义的。

我想说的是将业务逻辑放入应用层,但也有例外(主要是性能原因)

业务应用程序'层'是:

1。用户界面

这实现了业务用户对h(is / er)作业的看法。它使用用户熟悉的术语。

2。处理

这是计算和数据操作发生的地方。涉及更改数据的任何业务逻辑都在此处实现。

3。数据库

这可以是:规范化的顺序数据库(标准的基于SQL的DBMS);一个OO数据库,存储包装业务数据的对象;等

什么去哪里

在进入上述层时,您需要进行必要的分析和设计。这将指示业务逻辑最佳实现的位置:数据完整性规则和有关数据更新的并发/实时问题通常会尽可能接近数据实现,与计算字段相同,这是一个很好的指针存储过程/触发器,绝对需要数据完整性和事务控制。

涉及数据含义和使用的业务规则大部分将在处理层中实现,但也会作为用户的工作流出现在用户界面中 - 按某种顺序链接各种流程这反映了用户的工作。

恕我直言。有两个相互冲突的问题与决定,其中商业逻辑上说,在一个关系数据库驱动应用程序:

  • 维护性
  • 可靠性

Re。可维护性:允许对有效的未来发展的业务逻辑属于在应用程序的一部分,是最简单的调试及版本控制。

Re。可靠性:当有重大风险的不一致、业务逻辑属于在数据库层。关系数据库可设计成检查限制数据,例如不允许空值中具体列,等等。方案时出现在你的应用程序设计其中一些数据需要在特定国家是太复杂了表达与这些简单的约束,可以使用一种触发或类似的东西在数据库层。

触发器是一个痛苦不断更新,尤其是当你的程序是应该运行在客户系统为你甚至没有访问过。但是,这并不意味着这是不可能跟踪他们或更新它们。S.洛特的论据他的回答,这是一个痛苦和理想是完全有效的,我将第二,已经有太多。但如果你继续这些限制中心当你第一次设计数据层和避免触发器使用和功能的任何东西,但绝对必需品,这是易于管理。

在我们的应用中,大多数商业逻辑的是应用程序中包含的层模型,例如发票知道如何初始化本身从一个给出销售订单。当一堆不同的东西被修改,依次为一套复杂的变化,这样,我们卷起来在交易保持一致,而不是选择一个存储的过程。计算的总量等。都完成了所有方法的模式层。但是,当我们需要非规范化的东西,为的性能或数据插入一个'变动表使用的所有客户找出其中的对象,他们需要到期在其届会议的高速缓存,我们使用的触发器/功能在数据库层插入一个新的行和发出通知(Postgres听/通知的东西)从这个触发器。

之后我们的应用程序在该领域的大约一年,使用数以百计的客户的每一天,我唯一会改变如果我们要从头开始,将于设计我们的系统用于创建数据库的功能(或存储程序,但是你想要的给他们打电话)与版本控制和更新他们在考虑从一开始走。

值得庆幸的是,我们有一些系统来跟踪模式的版本中,所以我们建造的东西的顶上到照顾的替代数据库的功能。它已经拯救了我们一些时间,现在如果我们认为需要替换它们从一开始,虽然。


当然,一切都改变当步骤以外的领域的关系型数据库的元组成的存储系统,如亚马逊SimpleDB和谷歌的大表.但是,这是一个不同的故事:)

我们在存储过程中添加了许多业务逻辑 - 它并不理想,但通常在性能和可靠性之间取得了良好的平衡。

我们知道它的位置,而无需搜索大量的解决方案和代码库!

可扩展性也是将业务逻辑放在中间层或应用层而不是数据库层的非常重要的因素。应该理解,DatabaseLayer仅用于与数据库进行交互而不是操纵返回到数据库或从数据库返回的数据。

我记得在某个地方读过一篇文章时指出,在某种程度上,一切都可以是业务逻辑的一部分,所以这个问题毫无意义。

我认为给出的例子是在屏幕上显示发票。用红色标记过期的决定是商业决策......

这是一个连续统一体。恕我直言,最大的因素是速度。如何尽可能快地启动和运行这个吸盘,同时仍然坚持良好的编程租户,如可维护性,性能,可伸缩性,安全性,可靠性等。通常,SQL是最简洁的表达方式,也恰好是性能最高,除了字符串操作等,但这是你的CLR Procs可以提供帮助的地方。我的信念是,无论您认为哪种方式最适合手头的事业,都可以自由地散布业务逻辑。如果你有一大堆应用程序开发人员在查看SQL时会把他们的裤子弄脏,那就让他们使用他们的app逻辑。如果您真的想要创建具有大型数据集的高性能应用程序,请尽可能多地在数据库中添加逻辑。解雇您的DBA并为开发人员提供他们的Dev数据库的最终自由。这项工作没有一个答案或最好的工具。您有多个工具,因此在应用程序的各个级别都成为专家,您很快就会发现,您需要花费更多的时间来编写有意义的表达式SQL,并在其他时候使用应用程序层。对我来说,最终,减少代码行数是导致简单性的原因。我们刚刚将一个仅有2500行应用程序代码和1000行SQL的sql rich应用程序转换为域模型,该模型现在拥有15500行应用程序代码和2500行SQL,以实现以前的sql rich app所做的工作。如果您可以将代码增加6倍作为“简化”代码。然后继续前进。

这是一个很好的问题!在我问过一个simliar之后我发现了这个问题问题,但这更具体。它是由于我没有参与制作的设计变更决定而产生的。

基本上,我被告知的是,如果数据库表中有数百万行数据,那么请考虑将业务逻辑放入存储过程和触发器中。这就是我们现在正在做的事情,将java应用程序转换为存储过程以实现可维护性,因为java代码已经变得复杂。

我发现这篇文章:商业逻辑大战作者还在一个表参数中创建了百万行,我觉得这很有趣。他还在javascript中添加了业务逻辑,javascript是客户端和业务逻辑层之外的。我之前没想过这个,即使我多年来一直使用javascript进行验证,还有服务器端验证。

我的观点是,您希望应用程序/中间层中的业务逻辑作为经验法则,但不要打算将其放入数据库的情况。

最后一点,还有另一个我正在工作的小组正在为研究做大量的数据库工作,他们正在处理的数据量是巨大的。但是,对于他们来说,他们在数据库本身中没有任何业务逻辑,而是将其保留在应用程序/中间层中。对于他们的设计,应用程序/中间层是正确的位置,因此我不会将表的大小用作唯一的设计考虑因素。

业务逻辑通常由对象以及封装,继承和多态的各种语言结构体现。例如,如果银行应用程序正在转移货币,则可能存在货币类型,其定义什么是“货币”的商业元素。是。这与使用原始小数来表示金钱相反。出于这个原因,精心设计的OOP是“业务逻辑”的地方。生活—不严格地在任何层。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top