跨应用程序重用SQL存储过程
我很好奇人们在许多应用程序可以访问的数据库中使用存储过程的方法。具体来说,我们倾向于为每个应用程序保留不同的存储过程集,还是尝试使用共享集,还是混合使用?
一方面,当模型发生更改或者类似情况时,SP的重用可以减少更改,理想情况下可以减少维护。另一方面,如果应用程序的需求不同,则对一个应用程序的存储过程的更改可能会破坏其他应用程序。我应该注意,在我们的环境中,每个应用程序都有自己的开发团队,它们之间的沟通不畅。数据团队之间的沟通更好,并且主要负责存储过程的编写。
谢谢!
解决方案
回答
应基于要返回的数据(而不是发出请求的应用程序)创建存储过程。如果我们有一个存储过程GetAllItems,它将返回数据库中的所有项目。如果其中一个应用程序希望按类别获取所有项目,请创建GetAllItemsByCategory。没有理由根据请求数据的应用程序更改存储过程的业务规则。
回答
我相信我们问题的最后一部分会自行回答。
由于本来就很差的沟通,开发团队之间的共享程序只会增加潜在的故障点,并可能导致任何一个团队陷入困境。
如果我在同一个团队中从事多个项目,我们将节省一些时间并共享过程,但是通常我发现一些重复(这里和那里的一些过程)有助于避免以后在应用程序中需要进行灾难性的更改/重复开始分歧。
LordScarlet还指出了一个关键要素,如果它是通用的,没有业务逻辑共享,那也不是问题。
回答
我的经验是,让多个应用程序共享SP是造成痛苦的原因。实际上,我认为拥有一个可以被多个应用程序直接访问的数据库并不是最佳的长期架构。
我建议并已实现的模式是,只有一个应用程序应"拥有"每个数据库,并提供API(服务等)供其他应用程序访问和修改数据。
这有几个优点:
- 拥有的应用程序可以应用任何业务逻辑,日志记录等,以确保其保持稳定
- 如果更改了架构,则所有接口都是已知的,并且可以进行测试以确保外部应用程序仍然可以运行
回答
每当我们存储了多个应用程序共有的过程时,我们都会为这些过程(以及视图和表等)创建一个数据库。然后,该数据库(我们称为"基础")将由负责该数据库(维护和测试)的开发人员(或者团队)负责。
如果其他团队需要新功能,则可以编写它,而基础开发人员可以在基础数据库中实现它,也可以提出更简单的方法。
回答
我认为在多个应用程序之间共享Sprocs没有道理。
我可以看到在相关应用程序中共享数据库的情况,但是大概这些应用程序在很大程度上是分开的,因为它们对待数据的方式彼此非常不同。
使用相同的体系结构可以跨应用程序工作,但是可以想象一下,尝试在多个应用程序中使用相同的业务逻辑层。 "可是等等!"我们说:"这很愚蠢……如果我使用相同的BLL,为什么还要有一个单独的应用程序?他们做同样的事情!"
QED。
回答
可以这样想:存储过程是关于存储在其下的数据的,而不应该真正了解存储在其上的应用程序。一个应用程序可能需要以其他应用程序不需要的方式读取或者更新数据,因此一个应用程序将使用另一个应用程序不需要的SP。
如果是我的应用程序/数据库/等,而为了改进一个应用程序而对SP进行的更改又破坏了另一个应用程序,那么我认为这是更深层设计问题的证据。
回答
这完全取决于抽象策略。是将存储过程视为离散的抽象点,还是将它们视为调用它们的应用程序的另一部分。
答案将告诉我们如何管理它们。如果它们是离散的抽象,则可以共享它们,就像我们需要新的功能一样,我们将添加新的过程。如果它们是调用它们的应用程序的一部分,则不应共享它们。
回答
理想情况下,使用一个proc而不是多个版本。如果需要每个客户的版本,请调查每个客户1 db的想法,而不是所有客户1 db的想法。这还允许在不同服务器上进行一些有趣的数据库升级(将较大/较重使用率的数据库分配给较大的服务器,而较小的服务器则可以共享硬件)
回答
如果我们希望共享SQL代码,请尝试构建抽象函数库。这样,我们就可以重用一些执行通用功能的代码,并使每个应用程序的业务逻辑保持独立。可以将视图保持通用性并对许多应用程序有用的视图也可以这样做。
我们可能会发现,随着时间的流逝,通用存储过程的用途并不多。
就是说,我们曾经实施过一个项目,该项目正在使用设计非常糟糕的旧数据库进行工作。我们已经实现了一组存储过程,这些过程使信息检索变得容易。当来自其他团队的其他人希望使用相同的信息时,我们将存储过程进行重构以使其更加通用,添加了一层注释和文档,并允许其他人使用我们的过程。该解决方案效果很好。
回答
存储过程应公开不会因使用它们的应用程序而改变的业务规则。这样一来,规则就可以存储和更新一次,而不是每个规则都被使用,这是一场噩梦。
回答
我们尝试尽可能使用单个共享存储的proc,但是我们也遇到了我们描述的情况。我们通过在存储过程(ApplicationName_StoredProcName)中添加应用程序前缀来处理它。
通常,这些存储的proc称为集中存储的或者"主"存储的proc,但是此方法为将来特定于应用程序的更改留有空间。
回答
许多存储过程与应用程序无关,但可能有一些与应用程序相关。例如,CRUD(创建,选择,更新,删除)存储过程可以跨应用程序使用。特别是,我们可以引入审计逻辑(有时在触发器中完成,但是触发器的复杂程度是有限度的)。如果软件商店中有某种类型的标准体系结构,则中间层可能需要一个存储过程才能从数据库中创建/选择/更新/删除,而不管在哪种情况下共享该过程。
同时,可能存在一些查看数据的有用方法,例如GetProductsSoldBySalesPerson等。这也将与应用程序无关。我们可能有一些用于部门,地址等某些字段的查找表,因此可能会有一个过程返回带有所有文本字段的表的视图。即,该过程返回一个视图SalesPersonName,SaleDate,CustomerName,DepartmentName,CustomerAddress,而不是SalesPersonID,SaleDate,CustomerID,DepartmentID,CustomerAddressID。这也可以跨应用程序使用。客户关系系统将需要客户名称/地址/其他属性,就像计费系统一样。因此,在一次查询中完成所有联接并获得所有客户信息的工作可能会在整个应用程序中使用。公认创建视图数据的方法是视图的领域,但是人们经常使用存储过程来做到这一点。
因此,基本上,从表中删除时,我们需要从3个或者4个其他表中删除以确保数据完整性。触发器的逻辑太复杂了吗?然后,所有应用程序用来删除的存储过程可能很重要。在创建时需要做的事情也是如此。如果有经常执行的普通联接,那么有一个存储过程来执行所有联接可能是有意义的。然后,如果以后我们更改周围的表格,则可以保持该过程不变,而只需更改其中的逻辑即可。
回答
在多个应用程序之间共享数据模式的概念很困难。出于性能方面的考虑,架构总是会受到损害:非规范化,即要创建的索引。如果我们可以将行的大小减半,则可以将每页的行数加倍,并且有可能将扫描表的时间减半。但是,如果仅在主表上包括"公用"功能,并且仅使不同(但相关)表上的特定应用程序感兴趣的数据保持不变,则我们必须四处联接以回到"单表"的想法。
支持不同应用程序的索引越多,插入,更新和删除每个表中的数据的时间将越来越多。
数据库服务器通常也将成为瓶颈,因为数据库无法进行负载平衡。我们可以跨多个服务器对数据进行分区,但这也变得非常复杂。
最后,所需的协调程度通常非常大,毫无疑问,不同部门之间的争执需要优先考虑,而新的发展将陷入困境。
通常,"每个应用程序隔离数据孤岛"模型的效果更好。我为合同软件公司所做的几乎所有工作都是基于使用应用程序自己的数据库从其他系统导入数据和将数据导出到其他系统的。
在数据仓库/决策支持系统中可能会更容易;我通常在事务处理性能至关重要的OLTP系统上工作。