14

为了使代码更易于维护(即更容易在不重新编译代码的情况下更改业务规则),将代码放入存储过程中的论据是什么?

在其他条件相同的情况下,是什么使存储过程更好/更差于维护?

4

19 回答 19

22

出于多种原因,存储过程是一种不好的做法。

其中最重要的一项是关注点分离。使用存储过程,您在数据层中拥有业务逻辑,而不是在它所属的服务层中。这样做的一个结果是,您现在拥有一种语言,而且只有一种语言可以用来实现您的业务逻辑。随着新技术的出现,您没有好的迁移路径。

避免存储过程的另一个充分理由是存储过程在您和数据库供应商之间建立了牢固的联系。更改为不同的数据库供应商将非常困难,而在服务层中拥有您的业务逻辑将允许您非常轻松地换出数据库。因此,存储过程为 DB 供应商提供了很大的好处,而对您来说却没有那么多好处。

其次,可扩展性。在中间层创建服务并将它们分布在集群中非常简单。你将如何使用存储过程来做到这一点?我认为将存储过程集群到甚至八台机器上是非常困难的。

其次,与其他系统的集成。如果您的系统从您的数据库中提取数据,依赖于存储过程,以及来自其他系统的其他数据,那么该逻辑几乎肯定必须在服务层中。如果你的一些业务逻辑在服务层,而一些在业务层,你就会遇到一些维护麻烦。

于 2009-02-27T01:23:04.993 回答
11

这可能取决于您的系统。对我们来说,几乎只使用存储过程。我们只有一个网站,因此将 SQL 语句保存在存储过程中可以让我们的 DBA 更轻松地调整查询并重新创建导致问题的性能。

于 2009-02-27T00:37:30.127 回答
11

想想替代方案...

  • 将查询硬编码到您的系统中
  • 根据用户输入构建查询字符串
  • 让您的代码根据您的业务实体和数据库命名约定(通过 ORM、LINQ、CodeDom 等)动态生成查询
  • ETC...

然后考虑您的要求和环境...

  • 您的开发人员是否熟悉您的数据库管理工具,或者您是否有更多的数据库程序员和管理员处理然后围栏的数据库端?

  • 您是否需要频繁更改数据库架构?

  • 安全性如何?您是否需要一直到数据库用户级别的安全性?在代码或数据库中管理安全性会更容易吗?

  • 您的开发人员是否会使用 ORM 提高工作效率,而不必为自己编写 DAL,或者是否会增加复杂性,您希望以自定义方式将 ORM 无法提供的 DAL 添加到您的 DAL 中?

  • ETC...

人们会对 procs 是否更容易维护有不同的看法,这取决于他们所工作的系统和环境可能与你自己的相差甚远。您可能应该做的不仅仅是想知道它们是否更易于维护,而是弄清楚它们是否适合您的需求。这是一个非常好的问题,但也许编辑您的帖子并解释更多关于您的环境的信息。你可能会得到一些更有针对性的建议。

于 2009-02-27T02:02:45.990 回答
9

与在应用程序中保留查询相比,存储过程提供了许多优势,并且已经提到了很多。

存储过程充当应用程序和数据之间的抽象层,抽象层很少是坏事。

如果您有级联数据库操作,您可以实现一定程度的重用。Delete_Employee例如,该过程可以在事务中调用该过程Delete_Address,并通过来自应用程序的单个数据库请求执行许多其他操作。

存储过程下方的视图层可用于将应用程序与架构更改和查询/连接性能调整隔离开来。

存储过程层是可靠的企业架构和框架的重要组成部分。这些存储过程不应该包​​含任何业务逻辑,当然,它们应该只传递数据而不是操作它。

为了实现这些好处,良好的纪律是为了在应用程序的所有过程中保持一致性和相同的粒度。我处理过包含 100 多个程序的应用程序。如果所有这些查询都在代码中,那么实现数据级安全性会更加困难,如果不是不可能的话。可以轻松生成存储过程。我觉得使用存储过程的整体生产力比没有的要高。当然,存储过程应该在源代码控制中,就像所有其他数据库对象一样。

于 2009-02-27T02:28:58.987 回答
6

如果您的基础软件部署在多个不同的客户站点,则每个客户所需的大部分定制都可以通过数据库(视图和存储过程)来完成。您几乎可以将 SP 视为一个 INTERFACE,来回传递标准数据,而不用关心里面发生了什么。

当然,这也可以通过其他方式进行处理,例如每次安装的自定义 .dll 数据层。

但在某些情况下,SP 中的定制而不是 .dll 允许更快的定制,并允许 DBA 或数据专家接管,让程序员继续编码。

请记住,与编译后的代码相比,SP 中的代码可供更多人(在本例中为客户)使用。这可能是好是坏,取决于您的情况。

在某些企业中,更改存储过程在政治上比重新安装软件更容易(这更多地取决于谁有更严格的规则、开发人员和项目经理、DBA 或 IT/帮助台)。

于 2009-02-27T00:49:01.190 回答
4

我的经验是,很少像维护应用程序代码那样勤奋地使用源代码控制来维护数据库。当然,情况可能并非总是如此,但 15 年来我从未见过。这意味着您更有可能让人们在开发中进行更改,并且天堂禁止实时数据库存储过程,而没有真正考虑到易于维护,因为它太容易了。

于 2009-02-27T01:31:34.553 回答
3

我并不是反对存储过程,但我建议它们更难维护,因为它们必须独立于应用程序的更新进行更新(它们必须存储在 sql server 中)。

于 2009-02-27T00:36:45.887 回答
2

平等,这是一种不好的即时改变习惯,你还记得吗?
说真的,在存储过程中编写代码可以确保您的 SQL 交互更快
但是您的更改与 source-control 相去甚远。(据我所知,对于源代码控制,您需要导出)

于 2009-02-27T00:50:24.807 回答
2

根据我的经验,我认为主要的缺点是很少有与我共事过的开发人员对 SQL 感到非常满意(首先编写它,调试它)所以你必须确保你将拥有正确的技能团队要能够维护很多SQL。

如果您有多个平台(例如 Windows 和 Web 应用程序)或者将旧应用程序移植到新技术,则可以重用数据库过程,这是一个很大的优势。

我正在使用的应用程序在存储过程中有很多业务功能,我们修复的错误可能有一半是在 SQL 代码中,如果关键可以通过替换存储过程来快速修复,而不是在必须等待下一个版本的应用程序代码。(但另一方面是,如果我们没有编写这么多 SQL 代码,我们可能一开始就有更少的错误,谁知道呢!)

于 2009-02-27T01:20:36.077 回答
2

我在商业界从事 CRUD 编程已经 10 多年了。我可以告诉你,我在存储过程和视图中加入了尽可能多的业务逻辑(并且是有道理的)。每当风吹草动时,需求往往会发生变化,并且数据库中的逻辑使其易于更改并且(带有体面的评论)它是自我记录的。加上 sprocs 可提供良好的安全性并易于代码重用。

FWIW 我对所有存储过程都使用源代码控制和严格测试。否则只是懒惰。

于 2009-02-27T02:19:27.900 回答
2

出于多种原因,存储过程是一个好主意:

通过使业务逻辑更接近数据,您可以拥有任意数量的数据客户端接口。您可能最初为网站设计前端,但现在他们需要报告。没问题,业务逻辑在数据旁边。打开 API,在程序前面放置一个 Web 服务。您想使用最热门的新语言,请继续。业务逻辑在数据旁边。

使用存储过程的另一个原因是它在您和所选数据库之间建立了牢固的联系。通过这种方式,您可以利用您支付的数据库的内置功能(或在开源的情况下使用)。猜猜看,如果您尝试使您的应用程序数据库独立,您可能会遇到许多难以追踪的错误。 读取一致性在每个供应商的数据库上的工作方式不同。

您可以利用数据库内置的可伸缩性(集群、RAC——不管它们如何实现)。无需自己编写。

编写不使用绑定变量的代码更难(如果您需要更多信息,谷歌软解析与硬解析)。

版本控制——我一直对存储过程使用版本控制的公司。您通常在某个编辑器中编写存储过程。现在大多数编辑器都内置了对至少一种主要版本控制系统的支持。

外部代码必须通过网络提取数据,然后使用它。

最后,并非所有的程序语言都是平等创建的。MySQL 刚刚发布了使用存储过程的功能,它们为您提供了多种可以使用的语言,包括它们自己的语言。我怀疑他们是否经得起 Oracle 或 SQl Server 的考验。我不打算讨论谁是最好的,因为我不是甲骨文的专家。Oracle 的 PL/SQL 有很多在 DB 内核中优化的功能。我相信 MS SQL 也能做到这一点。

希望这会有所帮助(并且有意义 - 漫长的一天)。

于 2009-02-27T02:26:12.363 回答
1

在我工作的项目中,大部分的维护都可以通过改变sql程序来完成。所以是的,存储过程在我的情况下更易于维护,而且它们比从代码中执行 sql 语句具有更好的性能。

于 2009-02-27T00:42:56.323 回答
1

通常,提出该论点是因为您正在对存储的过程进行临时更改,而不是通过编译代码将通过的版本控制、测试等。

我对此没有立即的下意识反应(与这里的大多数人不同),但我会说在那种牛仔环境中编译和部署 DLL 并没有那么难。或者,您可以使用 CS-Script 之类的东西,它允许您保留按需编译的原始 .cs 文件。

我一直发现很难对存储过程进行版本控制和测试,而大多数代码都很容易完成。此外,大多数 RDBMS 过程语言都非常原始 - 所以你没有当代语言给你的表现力或抽象性。

当然,版本控制是一件好事——而且,对于大多数地方来说,开发人员和生产之间的一些过程检查也是如此。;)

于 2009-02-27T00:58:17.550 回答
1

有些人会争辩说,业务逻辑在存储过程中没有位置,并导致系统无法维护。我要指出,这些论点主要来自 DDD 和 N-Tier 的观点,他们寻求将所有业务逻辑放在应用程序层的特定区域中。虽然这是一个有价值的目标,但还有其他观点值得考虑。SP 还可以做的不仅仅是内部业务逻辑。

顺便说一句,Oracle 世界认为其最佳实践是将所有业务逻辑都放在数据库上的 PL/SQL 代码中,而且他们对关系数据库略知一二!

考虑 SP 的这些用途:

表现。在一个 SP 中运行多个 SQL 语句通常很有用,从而避免您的应用程序多次往返于数据库,从而有时会显着提高性能。

更换管理层。只要您对版本控制和部署过程有纪律,SP 就易于维护和修改。

SP 可以在不中断的情况下发布到实时生产系统,这在 24/7 运营中可能是一个相当大的优势。当然,您仍然需要严格控制发布过程。

抽象层。SP 可以从应用程序中抽象出 DB 模式的详细信息,前提是所有 app/db 交互都通过 SP。这可能是一个非常强大的概念。考虑到数据库的生命周期通常会比应用程序寿命更长 - 应用程序来来去去,并且经常使用最新的技术和架构模式重新编写,但有价值的数据会在同一个旧的关系数据库中保存很长时间。通常,多个应用程序是在同一个数据库上开发的,即使这从来都不是最初的意图。这些场景中的 SP 用于在应用程序和数据库之间提供一个紧密、定义良好的 API,可以对其进行仔细控制,以确保与多个应用程序甚至同一应用程序的多个版本进行一致的交互。

db schema 和 app 之间的关注点分离使应用程序程序员可以自由地做他们最擅长的事情,同时让 DBA 可以自由地随着时间的推移改进 schema 而不会破坏应用程序。

无论您采用何种架构模式,SP 都可以发挥重要作用。不要排除任何设计,就像任何工具一样,在有意义的地方使用它。

于 2010-01-20T02:08:20.757 回答
0

我再谈一件事关于版本控制。在我的上一份工作中,我添加了一个每天运行的第 3 方打包,并存储每个对象的 DDL 或代码的副本(如果它从上次备份时发生更改)。它本身是存储过程,因此可以手动或通过触发器运行,无论您希望它如何运行。它本身就是一个版本控制系统。

这是一个相当不错的工具,只需大约 200 美元。它甚至带有一个差异工具来向您展示发生了什么变化。

于 2009-02-27T02:37:50.383 回答
0

我们已经从使用存储过程转换为基于代码的业务逻辑生成的 DAL,原因有很多:

  1. 独立于数据库 - 通过使用内联 SQL 或生成 DAL(均符合 ANSI),更容易从 Oracle 切换到 Postgres 再到 SQL Server 等。
  2. 强制源代码控制(我承认这在任何一种情况下都可以使用,但对我们来说帮助很大)
  3. 无论如何,我们升级 GUI 比数据库更频繁,所以这降低了我们的升级复杂性
  4. 开发人员更容易调试客户端问题
于 2009-02-27T03:35:23.240 回答
0

这真的取决于存储过程的编写情况,不是吗?如果从业者编码时没有经过深思熟虑,T-SQL 和 PL-SQL 可能会变得像 C# 或 COBOL 一样粗糙且难以维护。

我最近进行的一项改进是,我故意将功能放在存储过程中,主要是因为我希望该功能更易于引用,更少维护(存储过程可以从数据库级别和客户端级别调用; 如果我将逻辑放在不同的层,那将是不正确的)。我认为我在使 PL-SQL 相当模块化方面做得很好,但是当 TOAD 分析它时,4 个部分中有 3 个得到了很好的分数,最后一个因高圈复杂度而受到重创。呵呵,我想我已经证明了自己的观点!

于 2009-02-27T03:42:49.120 回答
-1

存储过程的两个优点

我认为影响这一点的一个因素是客户端的数量,因为它可以在无需重新部署应用程序的情况下进行架构更改。例如,作为一个 DBA,我发现在调整 SQL、解决错误等时访问一个存储过程而不是 X 客户端来更改 SQL 语句要容易得多,当 X 是一个很大的数字并且“访问”它们意味着部署新版本的应用到多个工作站。

正确完成还意味着应用程序使用的模式可能与数据存储模式不同。例如,我喜欢高度规范化数据模式并提供一组视图和应用程序使用的存储过程。应用程序架构会随着应用程序代码的更改而及时更改,并且独立于数据架构。这是多应用系统的真正优势(例如,一个读写应用程序和一个使用相同数据的网站应用程序。)

存储过程的缺点之一

通常有一组不同的工具和不同的语言用于编写存储过程。这可能会阻碍需要培训、技能发展等的吸收。

于 2009-02-27T01:05:17.330 回答
-1

我更喜欢不使用存储过程,因为我喜欢保持相对数据库不可知论。如果出现更好的关系数据库,我希望可以选择迁移到它。存储过程会锁定你。也就是说,我偶尔会使用它们,它们可能非常强大。

于 2009-02-27T01:53:02.053 回答