存储过程是否违反了三层分离?


41

我的一些同事告诉我,数据库中的存储过程中包含业务逻辑违反了三层分离架构,因为数据库属于数据层,而存储过程是业务逻辑。

我认为如果没有存储过程,世界将变得非常严峻。

他们真的违反了三层分离吗?


9
只是问问他们是否听说过3 1/2层架构...
dreza 2012年

7
请记住,层和层不是相同的。
NoChance 2012年

2
@ emmad-kareem这个问题对我有帮助(stackoverflow.com/questions/120438/…)。问题是西班牙语(我的母语)语言技术文献为此使用了一个单词(“ capa”),而英语则有两个非常不同的单词。
图兰斯·科尔多瓦

1
@ user1598390,您是对的,这是很对的,特别是在使用一种语言进行定义时,软件世界不够严格,更不用说跨语言了。
NoChance 2012年

1
3-层体系结构是一个逻辑概念,而不是物理概念。您可以使用存储过程来实现业务规则,并且虽然物理上在数据库中,但是这些存储过程仍然是业务逻辑层的一部分。
Craig

Answers:


33

您的同事正在将架构与实现混为一谈。

多层应用程序背后的想法只是将其分解为几个部分,这些部分封装了某些类型的处理(存储,业务逻辑,表示),并使用定义明确的接口相互通信。正如可以用非面向对象的语言成功完成类似于面向对象的编程的工作一样,也可以对一个环境(例如数据库服务器)中的多层执行相同的操作。这两个成功的共同点是需要谨慎,纪律和对所涉及折衷的理解。

让我们看一个三层应用程序,其中两个层已在数据库上实现:

  • 数据层: 使用四个标准表操作访问数据库表由(INSERTUPDATEDELETESELECT)。
  • 逻辑层:由仅实现业务逻辑并仅使用上述方法访问数据层的存储过程组成。
  • 表示层: 由运行Web服务器的代码组成,该代码通过仅进行存储过程调用来访问逻辑层。

这是一个完全可以接受的模型,但是需要进行一些折衷。业务逻辑的实现方式使它可以快速,轻松地访问数据层,并且可以允许执行数据库外部逻辑层必须“艰难地”完成的工作。您所放弃的是能够轻松地将任一层迁移到其他技术和无忧无虑的实现的能力(即,您必须格外小心,这些层不使用数据库中可用但位于其定义的接口之外的功能) 。

在给定的情况下,这种事情及其带来的取舍是否可以接受,这是您和您的同事必须根据自己的判断来确定的。


2
因此,无论它们存储在数据库中的事实如何,我是否可以将它们视为存储过程是逻辑层的一部分?
图兰斯·科尔多瓦

3
@ user1598390:是的。虽然说3层而不是3层将是一层。
jmoreno,2012年

4
@ user1598390:只要可以证明,就可以说。表示层SELECT第一次直接来自表(数据层)时,模型已被破坏。
Blrfl 2012年

@blrfl我已经处理过这件事;)
TulainsCórdova

2
@ user1598390:很好,只需记住目标是逻辑上的关注点分离,而不是将事情放在不同的硬件上。
jmoreno,2012年

19

存储过程功能强大,可以通过将业务逻辑引入RDBMS层来编写违反三层分离的代码。但是,这是您的决定,而不是存储过程的固有缺陷。您可以将SP限制为满足数据层的需求,同时将应用程序逻辑保留在体系结构的应用程序层中。

当您需要存储过程(特别是一组触发器)来包含业务逻辑时,分离规则有一个罕见但重要的例外。当您的应用程序需要产生大量涉及数百万行的即时数据聚合时,就会发生这种情况。在这种情况下,可以设置触发器以维护预先聚合的数据以供业务层使用。仅在没有预先聚合的情况下应用程序运行缓慢的情况下才应执行此操作。


7
+1表示出于性能原因,有时您希望某些逻辑存在于数据库中,因为RDBMS通常会将操作设置的数量级比应用程序代码快几个数量级。尽管显然只有在性能至关重要且应用程序代码无法满足这些要求的情况下,现代数据库支持的绝大多数应用程序才是CRUD应用程序,对于这些好处零用。
吉米·霍法

1
阿们 人们似乎认为sprocs =业务“代码”。应该将它们视为DB“ API”,然后它们变得更加有意义。当然,他们还可以解决一些需要从逻辑上提高性能的情况!
gbjbaanb

5

阿特伍德(Atwood)从2004年开始的建议至今仍然有效,只有现在我们也能从ORM中受益。

http://blog.codinghorror.com/who-needs-stored-procedures-anyways/

应将存储过程视为数据库汇编语言:仅在性能最关键的情况下使用。有很多方法可以设计可靠的高性能数据访问层,而无需借助存储过程。如果坚持使用参数化SQL和单个一致的开发环境,您将实现很多好处。


在我在大公司的20年经验中,存储过程不用于返回行(用于视图),也不用于每个简单的插入或更新(内联sql)。它们主要用于不需要用户交互的长时间操作,需要迭代访问大量数据以基于某些业务逻辑连续汇总和执行插入或更新,例如月末结算或每日交易批处理。本文的作者似乎正在使用存储过程返回行,这就是为什么他加热它们。
图兰斯·科尔多瓦

3

简介:这实际上取决于您对存储过程的使用和业务需求。

许多项目确实使用三层体系结构,根据业务需求的性质,可能需要将某些操作转移到数据层。

说到术语,通常将这些层描述为:

  • 表示层或用户服务层-使用户可以访问应用程序。
  • 中间层或业务服务层-由业务和数据规则组成。
  • 数据层或数据服务层-与通常存储在数据库或永久性存储中的持久性数据进行交互。

通常对于给定的体系结构,中间层或业务服务层由业务和数据规则组成。但是,有时通过设置存储过程集来转移繁重的基本操作和/或数据规则以在数据层中完成,会产生很大的不同。

三层设计的好处是:

在应用程序的生命周期中,三层方法提供了诸如重用性,灵活性,可管理性,可维护性和可伸缩性等优点。您可以共享和重用创建的组件和服务,还可以根据需要在计算机网络中分发它们。您可以将大型项目和复杂项目划分为简单项目,然后将它们分配给不同的程序员或编程团队。您还可以在服务器上部署组件和服务以帮助跟上变化,并且可以随着应用程序用户群,数据和事务量的增长而重新部署它们。

因此,这实际上是一种基于案例的方法,其本身具有折衷。但是,Microsoft 的三层体系结构模型设计指南建议将业务逻辑保持在中间层。


2

层实际上意味着不同的机器,层意味着不同的逻辑分离。使用存储过程,数据层和业务逻辑层(至少一部分)在同一层中。将业务逻辑放入存储过程中会违反3层架构,但是否会违反3层架构值得怀疑。可以肯定的是,这肯定不是分离关注点的好例子。

层是构成软件解决方案的元素的逻辑结构化机制。层是系统基础结构的物理结构化机制。(参考

我认为在数据库中构建业务逻辑存在两个主要问题:

  1. 代码和库:与C#,Java等相比,使用SQL,PL / SQL,TSQL等进行编程的程序员更少。编程语言还具有出色的IDE,强大的库和框架的优势。

  2. 横向可伸缩性:扩展系统的唯一方法是通过更改数据库的物理服务器来使用功能更强大的物理服务器,这是相当昂贵的(具有64 GB RAM的服务器);关系数据库横向扩展非常糟糕,甚至花费更多。同时,使用面向对象的服务器中的业务逻辑,您可以通过将服务器放置在多个节点上来很好地水平扩展(在Java中,许多应用程序服务器都支持此功能)。


-1

有时我们在办公室里进行过辩论,我赞成数据库开发,对此我有以下看法

  1. 如果您使用的是Oracle数据库,则应尽可能地利用PL / SQL,因为可以肯定的是,从现在开始投资的公司至少会坚持使用oracle 10年。昨天在应用程序中,您使用的是Oracle Forms,今天是.net Web窗体,然后是MVC,然后明天将使用angularjs,只需要restfull api。如果您在数据库中拥有最大的逻辑,则可以轻松地迁移到新的前端技术。
  2. 数据库开发是非常快速和非常有效的性能明智的选择。只是给你一个前景。在我们的项目中,有7位应用程序开发人员和1位数据库开发人员,其中80%的逻辑位于数据库中。
  3. 如果使用的是oracle,则可以使用实用程序将数据库过程直接转换为Res full Api。

应用程序开发人员最强烈的论据是,业务逻辑应独立于数据库,以便您可以轻松更改数据库。我认为,如果一家公司正在使用oracle,为什么他们会改用其他技术,反而更希望使应用程序逻辑过时。问题主要是缺少数据库资源的新人才,大多数人开始使用mysql或sqlserver的简单网站。然后,这些人成为高级主管,并对应用程序层产生了情感上的依恋:)他们甚至不想理解或辩论。


“如果使用的是Oracle数据库,则应尽可能利用PL / SQL。”存储过程会增加体系结构中通常最瓶颈,最难扩展的系统的负载。从版本控制和单元测试的角度来看,这也是一个痛苦的管理过程,因为“因为确定投资的公司从现在起至少10年会坚持使用Oracle。这只是胡说。什么让你有那个想法?如果您用愚蠢的PL / SQL程序垃圾填充系统,则可能使公司无法迁移到当代。那可能是真的。
JimmyJames
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.