我很好奇人们在由许多应用程序访问的数据库中使用存储过程的方法。具体来说,您是否倾向于为每个应用程序保留不同的存储过程集,是否尝试使用共享集,还是进行混合?

一方面,当发生模型更改或类似情况时,SP 的重用可以减少更改,并且理想情况下可以减少维护。另一方面,如果应用程序的需求不同,则对一个应用程序的存储过程进行更改可能会破坏其他应用程序。我应该注意到,在我们的环境中,每个应用程序都有自己的开发团队,他们之间的沟通很差。数据团队的沟通比较好,主要负责存储过程的编写。

谢谢!

有帮助吗?

解决方案

这一切都取决于您的抽象策略。存储过程是否被视为离散的抽象点,或者只是被视为调用它们的应用程序的另一部分。

答案将告诉您如何管理它们。如果它们是离散的抽象,则可以共享它们,就像您需要新功能一样,您将添加新过程。如果它们是调用它们的应用程序的一部分,则不应共享它们。

其他提示

存储过程应根据您要返回的数据创建,而不是根据发出请求的应用程序创建。如果您有一个名为 GetAllItems 的存储过程,它应该返回数据库中的所有项目。如果其中一个应用程序想要按类别获取所有项目,请创建 GetAllItemsByCategory。存储过程的业务规则没有理由根据请求数据的应用程序而改变。

我的经验是,让多个应用程序共享 SP 是一件痛苦的事情。事实上,我认为拥有一个由多个应用程序直接访问的数据库并不是最好的长期架构。

我推荐并已实现的模式是,只有一个应用程序应该“拥有”每个数据库,并为其他应用程序提供 API(服务等)来访问和修改数据。

这有几个优点:

  1. 所属应用程序可以应用任何业务逻辑、日志记录等。确保其保持稳定
  2. 如果架构发生更改,所有接口都是已知的,并且可以进行测试以确保外部应用程序仍然可以工作

存储过程应该公开业务规则,这些规则不会根据使用它们的应用程序而改变。这使得规则可以被存储和更新一次,而不是在每个使用它们的地方,这是一场噩梦。

可以这样想:您的存储过程是关于它们下面的数据的,而不应该真正了解它们上面的应用程序。一个应用程序可能需要以另一种应用程序不需要的方式读取或更新数据,因此一个应用程序会使用另一个应用程序不会使用的 SP。

如果这是我的应用程序/数据库/等,并且为改进一个应用程序而对 SP 进行的更改破坏了另一个应用程序,那么我会认为这是更深层次设计问题的证据。

我相信你问题的最后一部分已经得到了解答。

由于沟通本来就很差,开发团队之间共享程序只会增加潜在的失败点,并可能导致任何一个团队遇到困难。

如果我在同一个团队中处理多个项目,我们将节省一些时间并共享程序,但通常我发现一点重复(这里和那里的一些程序)有助于避免稍后应用程序时所需的灾难性更改/重复开始出现分歧。

LordScarlet 还指出了一个关键元素,如果它是通用的,没有共享业务逻辑,那么它就不应该成为问题。

每当我们有多个应用程序通用的存储过程时,我们就会为这些过程(以及视图和表等)创建一个数据库。该数据库(我们命名为“base”)将有一个开发人员(或团队)负责它(维护和测试)。

如果不同的团队需要新功能,他们可以编写它,基础开发人员将在基础数据库中实现它或建议更简单的方法。

我们尝试尽可能使用单个共享存储过程,但我们也遇到了您所描述的情况。我们通过向存储过程添加应用程序前缀(ApplicationName_StoredProcName)来处理它。

通常这些存储过程称为集中式或“主”存储过程,但这种方法为以后的应用程序特定更改留下了空间。

我认为在多个应用程序之间共享存储过程没有意义。

我可以看到在相关应用程序中共享数据库的情况,但想必这些应用程序在很大程度上是独立的,因为它们对待数据的方式彼此非常不同。

使用相同的架构可以跨应用程序工作,但想象一下尝试在多个应用程序中使用相同的业务逻辑层。“可是等等!”你说:“那很愚蠢...如果我使用相同的 BLL,为什么我需要一个单独的应用程序?他们做同样的事情!”

量子ED。

理想情况下使用一个进程而不是多个版本。如果您需要每个客户的版本,请研究每个客户 1 db 的想法,而不是所有客户 1 db 的想法。这还允许在不同服务器上进行一些有趣的数据库暂存(将较大/较重使用的数据库分配给较大的服务器,而较小的服务器可以共享硬件)

如果您寻求共享 SQL 代码的能力,请尝试构建抽象函数库。这样,您可以重用一些执行通用操作的代码,并使每个应用程序的业务逻辑保持独立。视图也可以做同样的事情 - 它们可以保持非常通用并且对许多应用程序有用。

随着您的使用,您可能会发现常见存储过程的用途并不多。

也就是说,我们曾经实施过一个项目,该项目正在使用设计非常糟糕的遗留数据库。我们实现了一组存储过程,使信息检索变得容易。当其他团队的其他人想要使用相同的信息时,我们重构了存储过程以使其更加通用,添加了额外的注释和文档层,并允许其他人使用我们的过程。该解决方案效果相当好。

许多存储过程是独立于应用程序的,但也可能有一些存储过程依赖于应用程序。例如,CRUD(创建、选择、更新、删除)存储过程可以跨应用程序。特别是,您可以添加审核逻辑(有时在触发器中完成,但触发器中的复杂程度是有限的)。如果您的软件商店中有某种类型的标准体系结构,则中间层可能需要一个存储过程来从数据库中创建/选择/更新/删除,无论应用程序如何,在这种情况下该过程是共享的。

同时可能还有一些有用的查看数据的方法,即GetProductsSoldBySalesPerson等。这也将是独立于应用程序的。您可能有一堆针对某些字段(如部门、地址等)的查找表。因此可能有一个过程返回包含所有文本字段的表视图。即,该过程返回视图 SalesPersonName、SaleDate、CustomerName、DepartmentName、CustomerAddress,而不是 SalesPersonID、SaleDate、CustomerID、DepartmentID、CustomerAddressID。这也可以跨应用程序使用。客户关系系统需要客户名称/地址/其他属性,计费系统也需要客户名称/地址/其他属性。因此,在一个查询中完成所有连接并获取所有客户信息的东西可能会跨应用程序使用。诚然,创建查看数据的方法是视图的领域,但人们通常使用存储过程来执行此操作。

所以基本上,当从你的表中删除时,你是否需要从 3 或 4 个其他表中删除以确保数据完整性。触发器的逻辑是否太复杂?那么所有应用程序用来进行删除的存储过程可能很重要。对于创建时需要做的事情也是如此。如果存在始终执行的常见联接,那么使用一个存储过程来执行所有联接可能是有意义的。然后,如果稍后您更改周围的表,您可以保持过程相同,只需更改其中的逻辑即可。

在多个应用程序之间共享数据模式的概念是一个困难的概念。由于性能原因,您的模式总是会受到损害:非规范化,创建哪些索引。如果可以将行的大小减半,则可以将每页的行数加倍,并且可能将扫描表所需的时间减半。但是,如果您仅在主表上包含“通用”功能,并仅在不同(但相关)表上保留特定应用程序感兴趣的数据,则必须在各处加入才能回到“单表”想法。

支持不同应用程序的更多索引将导致从每个表插入、更新和删除数据的时间不断增加。

数据库服务器通常也会成为瓶颈,因为数据库无法实现负载平衡。您可以将数据分区到多个服务器上,但这也变得非常复杂。

最后,所需的协调程度通常很大,毫无疑问,不同部门之间会为谁的需求优先而发生争执,新的开发将陷入困境。

一般来说,“每个应用程序隔离数据孤岛”模型效果更好。几乎我们所做的一切(我在一家合同软件公司工作)都是基于使用我们应用程序自己的数据库从其他系统导入数据或将数据导出到其他系统。

在数据仓库/决策支持系统中可能会更容易;我通常在 OLTP 系统上工作,其中事务性能至关重要。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top