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