存储过程中的业务逻辑与中间层

business logic in stored procedures vs. middle layer

我想使用 Postgres 作为 Web api 存储后端。我当然需要(至少一些)胶水代码来实现我的 REST 接口(and/or WebSocket)。我考虑了两个选择:

  1. 将大部分业务逻辑实现为存储过程,PL/SQL同时使用非常薄的中间层来处理REST/websocket部分。

  2. 中间层实现了大部分业务逻辑,并通过它的抽象 DB 接口到达 Pg。

我的问题是,在灵活性、可扩展性、可维护性和可用性方面,上述设计相互比较可能有哪些 benefits/hindrances?

我不太关心确切的中间层实现(它可以是 php、node.js、python 或其他),我对好处感兴趣以及实际架构设计选择的陷阱。

我知道我通过选择 (1) 失去了一些灵活性,因为很难将系统移植到 oracle 以外的系统,并且我的用户将被绑定到 postgres。在我的例子中,这不是很重要,数据库无论如何都打算成为系统的一个组成部分。

我特别感兴趣的是选择 (2) 的情况下损失的好处,以及两种情况下可能存在的陷阱。

我认为这两种选择都有其优点和缺点。 (2) 方法好,知名度高。大多数简单的应用程序和 Web 服务都在使用它。但有时,使用存储过程比 (2) 好得多。 下面是一些例子,恕我直言,很适合用存储过程来实现:

  • 跟踪行的变化。也就是说,您有一些 table 包含定期更新的项目,并且您想要另一个 table 包含每个项目的所有更改和更改日期。

  • 自定义算法,如果您的函数可以用作索引数据的表达式。

  • 您想在多个微服务之间共享一些逻辑。如果每个微服务都使用不同的语言实现,则必须为每种语言和微服务重新实现业务逻辑的某些部分。使用存储过程显然可以帮助避免这种情况。

(2) 方法的一些好处(当然有一些 "however" 会让你感到困惑 :D):

  • 您可以使用自己喜欢的编程语言编写业务逻辑。 但是:在 (1) 方法中,您可以使用 pl/v8 或 pl/php 或 pl/python 或 pl/whatever 扩展名使用您喜欢的语言编写过程。

  • 维护代码比维护存储过程更容易。 但是:有一些很好的方法可以避免代码维护方面的此类麻烦。即:迁移,这对每种方法都是一件好事。 此外,您可以将您的函数放入您自己的命名空间,因此要将重新部署过程重新安装到数据库中,您只需删除并重新创建此命名空间,而不是每个函数。这可以通过简单的脚本来完成。

  • 您可以使用各种 ORM 来查询数据并获得抽象层,这些抽象层可以具有更复杂的逻辑和继承逻辑。在 (1) 中很难使用 OOP 模式。 我认为这是反对 (1) 方法的最有力论据,我不能向其添加任何 'however'。