在中央数据库中创建功能还是在每个数据库中重复?


8

我的一位开发人员编写了一个SQL函数,该函数的功能类似于VB.Net函数(LastIndexOf),并希望将其发布。我的问题是将其放入中央数据库而不是将其放入每个用户数据库的原因是什么?

开发人员试图将其放在sys模式中的主数据库上,这样他就不必限定来自用户数据库的调用...

但是我不确定将其集中到每个用户数据库的有效借口(显然不是主数据库)是什么?


1
我认为其背后的想法可能类似于“假设错误修复时您会怎么做?转到每个数据库并分别修复每个副本?”
dezso 2012年

1
这里的管理开销无关紧要,因为我可以像更新单个数据库一样轻松地更新所有数据库
David George

您的开发人员知道吗?:)也许他/她认为它实现了这样的基本功能,所以它必须位于核心位置。
dezso 2012年

是。这是我的问题,应该被视为核心的某些东西应该是用户数据库的一部分,还是应该在单个公共数据库的所有数据库之间共享?
大卫·乔治

是的,我试图提出两个或多或少有效的论点,以支持集中化。我认为这可能是一个政策问题或您的个人喜好问题-从措辞可以明显看出您不喜欢这个主意。
dezso 2012年

Answers:


12

我更喜欢这样做:将函数放在实用程序数据库中,并在每个常规数据库中为其创建同义词。通过这种方式,您可以两全其美:

  1. 该对象只有一个副本要维护
  2. 开发人员不必提供三部分或四部分的名称

例如

USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO

这对于CLR功能特别强大,因为更改/部署这些功能会产生额外的管理开销。

而且,这比使用master(并标记为系统对象,不能保证可向前移植)更可取。我很想知道您的开发人员期望如何在sys架构中创建他的功能。

我确实了解到,在500个数据库中维护一个函数的多个副本并不比维护单个副本真正困难,但是拥有多个副本实际上仅在您确实有异常时才有好处(例如,客户端A希望其函数以不同的方式处理NULL,或者其他的东西)。在这种情况下,我会将同义词保留在所有其他数据库中,并仅在该数据库中引入该函数的特殊版本。

(当然,此功能假定该函数不依赖于客户端数据库中的任何数据访问,这肯定会使事情复杂化。)


5

我将不得不不同意亚伦(以及公认的答案)。

Aaron的方法是我喜欢处理“ DBA内容”(例如维护脚本)的方式。我永远不会希望通过用户数据库调用的库函数来做到这一点。

为什么?您将前往DLL Hell的数据库等效版本。

不兼容的版本

...在Windows 2000之前,Windows易受此影响,因为COM类表已在所有用​​户和进程之间共享。可以将一个DLL / EXE中的仅一个COM对象声明为在系统上具有特定的全局COM类ID。如果需要任何程序来创建该类的实例,那么它将获得当前集中注册的实现。结果,安装公共对象新版本的程序的安装可能会无意间破坏了先前安装的其他程序。

在运行.net 2.0应用程序的服务器上安装.net 4.5,会发生什么?没什么,您正在应用程序继续使用2.0框架。在托管3个应用程序数据库的服务器上更新您的LastIndexOf函数(作为对其中一个应用程序的升级的一部分),会发生什么?这三个现在都使用最新版本。

替代方法是SQL#采用的方法。它已安装到每个用户数据库的架构中,因此您可以安全地为Application-X升级数据库,而不必担心Application-Y的稳定性。

如果您在严格控制的变更管理环境中工作,则别无选择,如果不测试组件的所有使用者,就无法升级共享组件。如果您在“快速而轻松”的地方工作,则可以随意利用补丁/升级无意间破坏某些内容。


让我提供一个反驳,因为您似乎想要一个,而现在我有一些时间可以空余,这是我以前没有的。:-)(1)我假设所讨论的数据库集都是相关的,并且不是完全不同的应用程序的一部分。(2)在这种情况下,我不认为调用LastIndexOf更改的功能有很大的危险,更不用说仅破坏某些应用程序/数据库的方式了。对于CLR或服务多个应用程序的真正的中央/复杂功能,这是一个更大的问题。(3)我的实际偏好是根本不将函数用于简单任务。
亚伦·伯特兰

1
当然,总是欢迎您的想法:)
Mark Storey-Smith

嘿。作为SQL#的创建者,我非常感谢积极提及:-)。但是,我应该澄清一下,为所有SQL#对象使用单独的架构的主要决策点是创建一个名称空间,这样无论在何处安装SQL#,都不会出现命名冲突。尽管如此,您确实提出了有关版本控制的观点,这取决于应用程序的结构。就个人而言,我喜欢拥有一个Utility通常用于库的数据库,但这确实增加了风险,并且需要进行全面的测试。
所罗门·鲁兹基

0

这个问题的答案取决于我们是在谈论T-SQL对象还是SQLCLR对象。处理SQLCLR对象时,需要考虑不同(更多)因素。

在T-SQL对象方面,这两个答案都提出了有效的观点。如@Aaron的答案中所述,中央数据库可以非常方便,并且可以使用同义词使某些DB指向共享资源而某些DB使用本地资源变得容易。但是,马克的回答中提出的关于由于更强的依赖性而导致的风险增加的观点不能忽略。

但是,如果要处理SQLCLR对象,则首先需要考虑以下答案中提出的所有要点:

如何从性能角度更好地使用CLR功能(在每个DB内重复或具有常规功能)?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.