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

Dav*_*rge 8 performance sql-server ddl functions

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

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

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

Aar*_*and 12

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

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

例如

USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO
Run Code Online (Sandbox Code Playgroud)

这对于 CLR 函数尤其强大,因为更改/部署这些函数会产生额外的管理开销。

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

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

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


Mar*_*ith 5

我将不得不不同意 Aaron(以及已接受的答案)。

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 的稳定性。

如果您在严格控制的变更管理环境中工作,您将别无选择,如果不测试组件的所有使用者,就无法升级共享组件。如果您在更“快速和松散”的地方工作,您可以自由地冒险通过补丁/升级无意中破坏某些东西。