将应用程序逻辑放入数据库层的论据是什么?


74

注意:programmers.se和dba.se的受众是不同的,并且会有不同的观点,因此在这种情况下,我认为重复存在什么理由或将应用程序逻辑放入数据库层是有道理的关于程序员。

我已经找不到关于dba的讨论了,原始帖子说明了一切,所以:

大多数软件开发人员都希望将应用程序逻辑保留在应用程序层中,对于我们而言,将其保留在此处可能很自然。数据库开发人员似乎希望将应用程序逻辑作为触发器和存储过程放在数据库层中。

就个人而言,我希望在应用程序层中保留尽可能多的内容,以使其更易于调试,并使各层的职责分开。

您对此有何想法,应该或不应该在数据库层中实现什么?

注意:我不是那个问题的OP,但是保留了原来的措词。


4
比较此处和SO的答案,差距是惊人的。开发人员抗议集中数据库中的流程所带来的延迟,但这对DBA来说是一件好事。 迫使人们花费更多时间和精力来请求新视图或存储过程,从而减少了与数据的接触点数量,从而更易于维护一致性并减少了优化点的数量。
所有行业的乔恩2012年

在我看来,这里的答案假设使用数据库的某种方式(多个应用程序,允许某些用户直接访问数据库等),我认为这是造成差异的主要原因。
JMD Coalesce

Answers:


56

各种各样的想法...

您的数据库代码将超过您的应用程序客户端技术。考虑一下ADO.NET-> Linq-> EF以及各种ORM。尽管您仍然可以使用上述所有客户端技术来运行最近千年的 SQL Server 2000代码。

您还遇到了多个客户端问题:我有.net,java和Excel。这是3套应用程序逻辑。

不应将“业务逻辑”与“数据完整性逻辑”混淆。如果确实有客户开始交易并进行各种检查,那将是很多数据库调用和长时间的交易。

应用程序逻辑不适用于高数据量。使用存储的过程,每秒有5万行。使用Hibernate的姐妹团队无法每秒获得一个


只要您留在关系数据库中
JMD Coalesce

1
@JMDCoalesce:您仍然需要业务逻辑并且易于拥有多个客户端应用程序,那么您的意思是?
gbn

40

我希望所有逻辑都适用于数据库中的所有用户和所有应用程序。那是唯一可放的地方。

我工作的最后一个《财富》 500强公司的应用程序至少以25种语言编写,并使用了OLTP数据库。其中一些程序在1970年代投入生产。

在数据库中实现这种要求的另一种方法是,让每个应用程序程序员每次启动编辑器时(从他们第一次进入公司之门直到公司退出),都可以100%正确地重新实现全部或部分信息。商业。

几率是多少?

这不是地球上最大的“ 不重复自己 ”活动吗?


这仅适用如果多个应用程序使用一个数据库
JMD合并

1
@JMDCoalesce在许多环境中很常见。主应用程序,Excel报告,服务器端报告,大量摘要:很快就可以添加了。几乎所有银行应用程序都有无数的客户端应用程序
gbn

当然,但并非所有应用程序都用于银行业务。
JMD Coalesce

29

我将旧的答案转移到那些未经程序员编辑的地方,因为答案似乎在站点之间是两极分化的。

我知道我很痛苦,但是将业务逻辑放入数据库中是因为:

  • 您可以允许业务高级用户直接访问数据库,而不必担心他们搞砸数据库(或比使用基于应用程序的逻辑少担心)
  • 超级用户可以创建新报告,而无需等待新软件发布。
  • 您可以在数据库副本中测试SP / TRIGGER代码,就像测试基于应用程序的逻辑一样
  • 您可以保留SQL以在文本文件中创建sp和触发器(无论如何对于表/视图代码都应这样做)
  • 您可以混合和匹配语言,而无需移植业务逻辑
  • 您可以更改业务逻辑,而无需升级所有软件
  • 审核结构的更改方式与审核数据库活动的方式相同-通过日志记录
  • 大大提高了安全性和细粒度的访问控制(大多数基于应用程序的逻辑实现均使用其自己的安全模型,因此数据更容易受到破坏。可逆密码加密并不罕见)
  • 数据库端用户安全性极大地减少了SQL可以造成的破坏/盗窃

缺点是:-当用户减少对定制报告的开发人员的依赖时,开发人员会受到威胁-开发人员需要学习另一种编程语言

对于熟练的开发人员而言,这些都不重要。

有趣的是,大多数答案都是用“应用程序逻辑”而不是“业务逻辑”来表达的,就好像没有提供业务功能的软件一样。


1
*存储的proc / triggers可以提供一定的抽象级别,使您可以在数据库中进行结构更改,而不必更改所有应用程序代码。*并非数据库的每个用户都会忠实地使用您的中间件。*来吧,外键业务规则!!*从数据库中删除所有检查/约束/代码意味着它无法保护自己免受不一致/损坏。*每个应用程序不要求队列驱动transactionless设计像一个eBay的发展,他们取得了成功,并有能力来构建。*伙计们,SQL并不那么难。
克雷格

23

最重要的问题是数据库上方的任何“层”是否都认为自己拥有数据。并发性和数据完整性是RDBMS解决方案所面临的问题-开发某些应用程序时,好像数据库只是它们的个人存储桶一样,当然,它们最终还是尝试以各种方式重新发明轮子一旦其他一些应用程序访问同一数据库,该文件将无法修复


1
我认为,赞助系统的人都拥有数据-他们已经为数据付费。另外,在解决并发问题之前,我还解决了很多问题-在许多情况下,这要容易得多。
AK

4
您使用的“自己”与我使用的含义不同:我的意思是,如果您在并发问题到达数据库之前“解决”并发问题,则还必须确保自己是唯一访问数据库的应用程序,否则必须解决它们再次在该级别。我同意投票结果最高的答案:“您的数据库代码将(可能)超过您的应用程序客户端技术的寿命。”
杰克·道格拉斯

17

在博客中写下了对此的答案。我的结论是,一旦考虑了整个应用程序生命周期,就无法在应用程序中进行扩展。


3. 向基础数据库添加完整性/检查约束,以数据库的存储过程语言实现的更复杂的代码。由此,我们可以维护一个中心位置,并且即使对于我们不知道的应用程序,也可以绝对地执行规则!在整个应用程序组合和整个生命周期中,我们都使用一种语言来表达业务规则,这是因为jour语言的更改比数据库更改的频率要高得多。它在已经与最重要的应用程序一样具有关键任务的系统上运行。错误由处理这些应用程序中数据库错误的现有代码处理。当然,仍然存在应用程序可能会崩溃的风险,但是在这三种情况下,这是最少的,只有发生故障的应用程序需要进行任何修改,并非所有这些都可以使用(如果确实需要,大多数SP /数据库机制将允许对一个应用程序进行例外处理)。认为这对您的新建站点或小型公司都没有关系吗?好吧,如果您的业务成功,那么在30年的时间里,您希望您已经注意到我的智慧!

…一些[异议]我经常听到:

  • 很难对数据库中部署的SP代码进行版本控制。我认为说要对部署在应用程序服务器中的Java代码进行版本控制很困难,也就是说,这并不困难,这很普遍。在Ruby-land上,整本书都写着关于如何将代码从开发环境移植到生产环境的书,这是其他语言社区似乎没有的难题。然而,控制存储过程的版本显然太困难了。
  • 存储过程很难测试。这是一个奇怪的。首先,SP是强类型的;编译器会告诉您是否存在没有意义的代码输入或输出,并且至少在Oracle中,它将为您计算所有依赖项。因此,这是您在Ruby中可能需要立即消除的一组通用单元测试。要测试OO代码,需要进行模拟以将对象强制为代表测试场景所需的内部状态-设置测试数据有何不同?除了PL / SQL和其他工具外,还有TAP生产商。也有调试器和分析器。
  • 存储过程语言不是功能齐全的语言。好吧,我们不是试图只在存储过程中编写整个应用程序!大多数专用的SP语言都具有您期望的所有现代结构,并且至少在Oracle中,您可以将Java存储过程与OO开发人员熟悉的所有语言功能一起使用,也可以将其与任何语言的外部过程一起使用。重要的是逻辑的实现位置-在一个地方,靠近数据-实际的语言只是一个细节。PL / SQL编译为本地代码,并在数据库中运行;没有比这更高的性能架构了。
  • 我不想学习另一种语言。忽略一秒钟,这对任何开发人员来说都是一个巨大的危险信号(尤其是一个提议修改生产应用程序(无论如何可能会使用其他语言)!),在任何现代环境中都有很多需要学习的知识:一个典型的Java商店可能具有Eclipse ,WebLogic,Maven,Hudson,Anthill,Subversion以及大量其他内容,在编写一行应用程序代码之前,您需要学习这些内容。相比之下,非常高级的SP语言的工作知识很简单,并且很可能会有专家或DBA来帮助您。更不用说开发人员喜欢的Hibernate带有自己的查询语言…


12

SQL是否会执行诸如设置逻辑和面向应用程序的结果过滤之类的事情?SQL是一种很棒的集合操作语言。

此外,正如上面的GBN所指出的,SQL代码将几乎普遍地超出应用程序代码的寿命。

确实可以使用EF或NHibernate或LinqToSql或其他任何方法使您更快地生成代码,但值得其性能的每个程序员都知道,只有优化SQL才能优化数据检索。RDBMS仅了解SQL,因此您必须先将所有内容都放入SQL中,然后再全部说完。(假设我们可以同意TSQL和PLSQL仍然是SQL)


11

人们不必讨论的一个缺点-优点在这里已经筋疲力尽-是成本。

在负担软件许可费用时,数据库服务器上的CPU通常是任何组织中最昂贵的CPU。因此,应谨慎地将业务逻辑移至数据层,而不必统一。


7

这是必然会发生思想交流的地方,也就是说,开发人员(DV)和DBA的思想。使用业务逻辑(BL)并将其存储在数据库中可能会产生使美化或使它的实施变得恐怖的影响。

对于某些RDBMS产品,存在用于业务逻辑和对象基础结构的高级库/工具/ API,人们可以快速学习并在其应用程序中使用它们。对于其他RDBMS,不存在任何库/工具/ API。

过去,客户端服务器应用程序通过存储过程(SP)成为BL的桥梁。对于Oracle和SQL Server等产品,这是提早完成的。随着诸如PostgreSQL和MySQL之类的开源数据库的兴起,使用它们的数据库面临着BL中存储过程开辟新局面的风险。PostgreSQL在这方面非常迅速地成熟,因为不仅实现了存储过程,而且还产生了制作客户语言的能力。MySQL基本上停止了在存储过程世界中的发展,并以一种简化的语言形式出现了很多限制。因此,当涉及到BL时,您完全可以依靠MySQL及其存储过程语言。

真正只有一个问题:无论是RDBMS,BL是否应全部或部分驻留在数据库中?

想想开发人员。当应用程序出现问题时,调试过程将使开发人员跳入和跳出数据库,以遵循可能偶尔间歇或不间歇正确的数据变化。就像编写C ++应用程序并在中间调用汇编程序代码一样。您必须从源代码,类和结构切换到中断,寄存器和偏移量,然后返回!这将调试带到了相同的水平。

开发人员可以通过位于内存而不是数据库中的业务对象,结合语言配置(C ++的编译器标志,PHP / Python的不同设置等),设计出一种执行BL的高速方法。有些人试图通过编写库来调试这种思想,以便更快地将代码运行到数据库中,在该库中,调试存储过程和触发器已很好地集成在数据库中并且几乎无法使用。

因此,开发人员面临着用两种语言来开发,调试和维护源代码和BL的挑战。

现在想想DBA。DBA希望保持数据库的精简性,并在存储过程领域中尽可能多地发挥作用。DBA可能会将BL视为数据库外部的东西。但是,当SQL调用BL所需的数据时,SQL需要精简而卑鄙。

现在,让思想见面!

开发人员对SP进行编码并使用迭代方法。DBA查看SP。DBA确定单个SQL语句可以替代开发人员编写的迭代方法。开发人员发现DBA建议的SQL语句需要调用其他BL相关代码或不遵循SQL语句正常执行计划的SQL。

鉴于此,配置,性能调整和SP编码成为BL用于数据检索的深度和数据强度的函数。BL的深度和数据密集度越高,提供给数据库的数据量和处理能力就必须在同一页上的开发人员和DBA越多。

结论

数据检索的方式应始终涉及Developer和DBA阵营。为了速度和效率,必须始终就哪种编码方法和数据检索范式可以协同工作做出让步。如果仅在代码获取数据之前一次准备供源代码处理的数据,则DBA应该指示使用精益和均值SQL。如果BL是DBA不适应的,那么控制权就在开发人员手中。这就是为什么DBA应该看到他/她自己和项目团队的一部分,而不是他/她自己的孤岛,而开发人员必须在允许的情况下让DBA对SQL进行微调。


4

在充满DBA的网站上提问是一个很好的问题。希望大多数答案都是“赞成”以保持数据库处于ACID状态,从而将业务逻辑保留在数据库中。:-)

就我的观点而言,我认为您应该在应用程序和数据库中都实现业务逻辑。这种方法将花费更多的时间和金钱,但我认为它将因此带来质量更好的业务解决方案。


1
两层逻辑相同吗?
dezso 2012年

如果您想创建一个新客户,并且必须存储他/她的姓名和一个客户编号(始终包含4个数字),我希望应用程序在将SQL语句发送到我的客户之前检查该客户编号是否有效数据库(知道该语句不会通过数据库中的业务逻辑)。
Ruud van de Beeten 2012年

2
所有业务逻辑都应在数据库中实现(因此请不要划分“逻辑”)。您可以轻松检入应用程序的所有内容(例如Javascript中的正则表达式)对于数据库的工作量较小(在输入无效的情况下)。
Ruud van de Beeten

2
+1这就是我的工作–我只是称其为“将业务登录名放入数据库中,并在应用程序中放置便利性检查”
Jack Douglas

1
您需要一种系统的方法来完成这项工作。使数据始终符合期望的核心完整性逻辑首先需要在数据库中完成。接下来,是要从异常情况的数据库中保持与应用程序的良好通信,然后客户端才能与用户充分通信。然后,在访问数据库之前先进行预测是最重复的部分,并且必须保持同步-如果您可以最大限度地减少保持同步的需求,那么最好。
Cade Roux

2

正如亚当·穆奇(Adam Musch)所说,在性能方面还有更多需要考虑的地方。CPU使用率。内存使用情况。

阻止明显错误的事情进入数据库。

  • 清除不符合某些基本要求的电子邮件地址。
  • 检查长度

当您变得更深入时,就需要做出决定。数据库服务器是执行客户端可以轻松完成的事情的非常昂贵的地方。例如:数据格式,格式日期,汇编字符串等客户端。

您是在客户端还是在数据库服务器上进行数学/处理?对我而言,这取决于所涉及的记录的复杂性和数量。实际上应该在数据库本身中完成业务逻辑,以便对所有事物进行相同的处理。
您确实应该创建一个用于读取和存储proc的视图API,以将数据写入数据库,以免日后头疼。

充分利用每一端的优势,以使您受益。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.