【问题标题】:What's the benefit of using a lot of complex stored procedures使用大量复杂的存储过程有什么好处
【发布时间】:2009-12-16 06:28:19
【问题描述】:

对于典型的 3 层应用程序,我看到在许多情况下,它们在数据库中使用了大量复杂的存储过程。我不能完全从这种方法中受益。以我个人的理解,这种方法有以下缺点:

  1. 事务变得粗糙。
  2. 业务逻辑进入数据库。
  3. 大量计算是在数据库服务器中完成的,而不是在应用程序服务器中。同时,数据库还需要做它原来的工作:维护数据。数据库服务器可能会成为瓶颈。

我猜它可能有两个好处:

  1. 无需编译即可更改业务逻辑。但 SP 比 Java/C# 代码更难维护和测试。
  2. 减少数据库连接数。但是一般情况下,数据库的瓶颈是硬盘io而不是网络io。

谁能告诉我使用大量存储过程而不是让工作在业务逻辑层完成的好处?

【问题讨论】:

  • 您将在硬盘驱动器之前 长时间 使网络连接饱和 - 100 Mb/s 连接 = 理论最大值为 12.2 MB/s。 PATA 达到 133 MB/s,SATA2 可以达到 3 GB/s
  • 不是一个真正的答案,但我在一个项目中,在数据库中有很多 SP,原因之一是项目人员的技能和经验。我们有很多人喜欢使用 PL/SQL“锤子”。因此,尽管有最佳实践,但大多数事情看起来都像是 PL/SQL 的“钉子”。
  • 您的问题似乎是基于三层是“方式”的概念。 Philip Greenspun 写了一个fairly scathing critic of the benefit of the three-tier architecture。尽管他的一些论点有些过时,但即使在今天,它们仍然具有一定的道理。
  • 阅读您的链接。我是一个大整合的支持者,所以也希望看到 90 年代后期的那些 cmets。

标签: database stored-procedures


【解决方案1】:

基本上,好处是您的问题列表中的第 2 个 - 如果您在数据库后端进行大量处理,那么它会在那里处理,而不依赖于访问数据库的应用程序。

当然 - 如果您的 应用程序在其业务逻辑层中做所有正确的事情,一切都会好起来的。但是,一旦第二个和第三个应用程序需要连接到您的数据库,突然之间他们也必须确保遵守所有业务规则等 - 或者他们可能不会。

将您的业务规则和业务逻辑放入数据库可确保无论应用、脚本、具有 Excel 的管理器如何访问您的数据库,您的业务规则得到执行,并且您的数据完整性将受到保护。

这是使用存储过程而不是基于代码的 BLL 的主要原因。

此外,使用视图进行读取和存储过程进行更新/插入,DBA 可以删除对基础表的任何直接权限。您的用户不再需要对表拥有所有权限,因此,您的表中的数据可以更好地防止意外或恶意更改。

使用存储过程方法还使您能够通过存储过程监控和审核数据库访问 - 没有人能够声称他们没有更改该数据 - 您可以轻松证明这一点。

总而言之:您的数据对业务越关键,您希望围绕它构建的保护层就越多。这就是使用存储过程的目的——它们也不需要很复杂——并且大多数存储过程都可以使用代码生成基于表结构生成,所以这也不是一个很大的打字工作。

【讨论】:

  • 我同意将BL放在DB中可以更容易地进行不同应用程序的开发。然而,根据我的经验,最常见的情况是我们只为一个数据库开发一个应用程序。我认为客户不喜欢让 2 个不同的团队在同一个数据库上开发不同的应用程序。如果是这样,为什么不让一个团队开发一个应用程序?
  • @Ryan - 为什么必须是两个团队?如果必须是一个团队,则将所有内容放入数据库中——布局、页面流程等等。从数据库中生成网页非常简单。
  • @Marc。事务性 API 很好,但在大多数情况下,表 API 不是。所以这是代码生成的一个大拇指。
  • @Raan: 是的,如果您的应用程序很小并且足够有限以确保没有其他人想要直接访问您的数据库 - 很好,那么您基本上可以做任何适合您的事情.我在企业环境中工作,其中大多数数据库在众多团队和应用程序之间共享。
  • 另一个优势可能是与数据库表交互的代码更有可能由对任务感兴趣/有动力/熟练的开发人员编写和维护。以我的经验,Java 程序员(例如)对数据库、数据库设计或 RDBMS 技术不感兴趣。
【解决方案2】:

不要害怕 DB。

我们也不要将 business 逻辑与 data 逻辑混为一谈,后者在 DB 中占有一席之地。

优秀的系统设计师将通过数据逻辑包含灵活的业务逻辑,即可以由(不)存在或数据行的属性驱动的抽象业务规则定义。

仅供参考,我使用过的最成功且可扩展的“企业/商业”软件实现将所有投影查询放入视图中,并将所有数据管理放入数据库过程或暂存表上的触发器中。

【讨论】:

  • 有趣的概念,能否请您扩展一下业务逻辑和数据逻辑的区别???
  • @opensas,很难在评论中解释,但“做什么”的逻辑应该(在该模型中)取决于数据。 IE。 (典型示例)应用程序将查询单个视图以确定要采取的步骤或要显示的内容,而不是追踪所有必要的数据,然后自行确定适用的内容。这同样适用于其他 CRUD 活动:允许模式处理所述逻辑,应用程序应该围绕它管理 UI。
【解决方案3】:

appServer 和 sqlServer 之间的网络经常是瓶颈。 当您需要进行复杂的查询时,需要存储过程。 例如,您想按姓氏收集有关员工的一些数据。尤其想象一下,DB 中的数据看起来像某种树——表 A 中有 3 条关于该员工的记录。表 A 中的每条记录在表 B 中有 10 条记录。表 C 中的每条记录有 100 条记录表 B。您只想从表 C 中获取有关该员工的 5 条特殊记录。如果没有存储过程,你会在 appServer 和 sqlServer 之间获得大量的查询流量,以及 appServer 中的大量代码。使用接受员工姓氏的存储过程,获取这 5 条记录并将它们返回给 appServer,您 1)将流量减少数百倍,2)大大简化 appServer 代码。

【讨论】:

  • 确实如此。现在我想把一些对于业务层来说太复杂并且不太可能作为SP更改为数据库的逻辑。剩下的,我还是会把剩下的放在业务层,因为易于维护和测试。此外,如果不使用 SP,此更改将影响更少的组件。
【解决方案4】:

我们数据的生命周期超过了我们的应用程序的生命周期。数据也在应用程序之间共享。如此多的应用程序会将数据插入数据库,许多应用程序将从数据库中检索数据。数据库对数据的完整性、完整性和正确性负责。因此,它需要有权执行与数据相关的业务规则。

带你具体点:

  1. 事务是工作单元。一世 不明白为什么要实施 存储过程中的事务 应该改变它们的粒度。
  2. 适用于 数据属于数据:那 最大化凝聚力。
  3. 很难编写好的 SQL 和 学习分组思考。所以 看起来数据库是 瓶颈。事实上,如果我们是 从事大量工作 与数据库的数据有关 可能是最有效的地方 做。

关于维护:如果我们熟悉 PL/SQL、T-SQL 等,维护比从外面看起来要容易。但我承认该工具对重构等方面的支持落后于其他语言。

【讨论】:

    【解决方案5】:

    您列出了将业务逻辑放入 Db 的主要方法之一,这通常给人印象,使其更易于维护。

    数据库中通常复杂的 SP 逻辑允许更便宜地实现实际实现代码,如果它是一个过渡应用程序(例如从遗留代码移植),它的代码需要以多种语言实现(例如实例在不同的平台或设备上上市)或者因为问题在数据库中更容易解决。

    另一个原因是,出于安全或性能原因,通常有一个通用的“最佳实践”将所有对数据库的访问封装在 sps 中。根据您的平台以及您使用它所做的事情,这可能是正确的,也可能不是正确的。

    【讨论】:

      【解决方案6】:

      我认为没有。您非常正确,将 BL 移至数据库是不好的,但并非对所有事情都适用。试试看Domain Driven Design。这是大量 SPROC 的解毒剂。我认为您应该将数据库用作存储业务对象的地方,仅此而已。

      但是,SPROC 在某些简单的功能上可能效率更高。例如,您可能希望将数据库中每个员工的工资提高一个固定百分比。这比通过 SPROC 从数据库中获取所有员工、更新它们然后将它们保存回来更快。

      【讨论】:

        【解决方案7】:

        我在一个项目中工作,其中每件事实际上都是在数据库级别完成的。我们编写了很多存储过程,并在数据库中做了很多业务验证/逻辑。大多数时候,这对我们来说是一个很大的调试开销。

        我觉得的优势可能是

        • 利用完整的数据库功能。
        • 数据库密集型活动,如大量插入/更新,可以在数据库级别更好地完成。调用 SP 并让它完成所有工作,而不是多次访问 DB。
        • 新的数据库服务器可以适应复杂的操作,因此它们不再将其视为瓶颈。哦,是的,我们使用了 Oracle。

        现在来看,我认为在应用程序级别可以做得更好,而在数据库级别做得更少。

        【讨论】:

          【解决方案8】:

          这几乎完全取决于上下文。

          在服务器上而不是在客户端上工作通常是一个坏主意,因为这会使您的服务器的可扩展性降低。但是,您必须权衡预期工作负载(如果您知道在封闭环境中只有 100 个用户,您可能不需要可扩展的服务器)和网络流量成本(如果您必须读取大量数据才能应用计算/处理,然后在服务器上运行这些计算并仅通过网络发送结果总体上会更便宜/更快)。

          此外,如果您有自定义客户端应用程序(而不是 Web 浏览器等),则可以很容易地将更新推送到您的客户端,因为您不需要重新编译和部署客户端代码,您只需升级数据库存储过程。

          当然,使用存储过程而不是执行动态编译的 SQL 语句会更有效(它是预编译的,代码不需要上传到服务器),并且有助于封装以提供更好的数据库完整性/安全性。但听上去,您是在谈论大量的业务逻辑,而不是简单的效率和安全措施。

          与大多数事情一样,需要合理的妥协/平衡。存储过程应该足以提高效率和安全性,但您不希望您的服务器变得不可扩展。

          【讨论】:

            【解决方案9】:

            "这种方法有以下缺点: ... 业务逻辑进入数据库。”

            就“业务逻辑”而言,您的意思是“业务规则的执行”,DBMS 正是“业务逻辑”所属的地方。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-11-12
              • 1970-01-01
              • 2016-11-03
              • 2014-04-25
              • 2013-06-22
              • 1970-01-01
              • 2020-03-31
              • 1970-01-01
              相关资源
              最近更新 更多