中央データベースに関数を作成するか、各データベースで繰り返しますか?


8

私の開発者の1人が、VB.Net関数(LastIndexOf)のように機能し、それを公開したいSQL関数を作成しました。私の質問は、これを中央データベースに配置するのではなく、各ユーザーデータベースに配置する理由は何ですか?

開発者はそれを自分のマスターデータベースのsysスキーマに配置しようとしていたため、ユーザーデータベースからの呼び出しを修飾する必要はありませんでした...ため息

しかし、私はそれを(明らかにマスターデータベースではなく)各ユーザーデータベースに対して集中化するための有効な言い訳が何であるかがわかりませんでしたか?


1
その背後にあるアイデアは、「架空のバグ修正の場合はどうしますか?すべてのデータベースに移動して、すべてのコピーを個別に修正しますか?」
dezso

1
すべてのデータベースを単一のデータベースと同じように簡単に更新できるため、管理オーバーヘッドはここでは問題になりません
David George

そしてあなたの開発者はそれについて知っていますか?:)そしておそらく彼/彼女はそれがまさにコアになければならないような基本的な機能を実装していると感じています。
dezso

はい。それが私の質問です。コアと考えられるものをユーザーデータベースの一部にするか、単一の共通データベースのすべてのデータベースで共有する必要がありますか?
デビッドジョージ

はい、私は中央集権化を支持して、多かれ少なかれ2つの有効な議論を提示しようとしました。むしろそれはポリシーや個人的な好みの問題かもしれません-あなたがそのアイデアを嫌うという文言から明らかです。
dezso

回答:


12

私がこれを行うのに好む方法:関数をユーティリティデータベースに入れ、各レギュラーデータベースにそのシノニムを作成します。このようにして、両方の利点を最大限に活用できます。

  1. 維持するオブジェクトのコピーは1つだけです
  2. 開発者は3つまたは4つの部分からなる名前を提供する必要はありません

例えば

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

これは、CLR関数を変更/展開するための追加の管理オーバーヘッドがあるため、CLR関数にとって特に強力です。

そして、これはmasterを使用するよりも望ましい方法です(そして、システムオブジェクトとしてマークすることは、前方移植が保証されていません)。sysただし、開発者がスキーマで関数を作成することをどのように期待しているのか知りたいです。

500個のデータベースで関数の複数のコピーを維持することは、単一のコピーを維持することと同じくらい難しいことではないことを理解していますが、複数のコピーがあることは、例外がある場合(たとえば、クライアントAがNULLを異なる方法で処理することを望んでいる場合)か何か)。その場合、他のすべてのデータベースに同義語を残し、そのデータベースでのみ関数の特別なバージョンを導入します。

(これはもちろん、関数がクライアントのデータベース内のデータアクセスに依存していないことを前提としています。これはもちろん問題を複雑にする可能性があります。)


5

私はアーロン(そして受け入れられた答え)に同意しなければなりません。

アーロンのアプローチは、メンテナンススクリプトなど、「DBAのこと」を扱うのが好きな方法です。ユーザーデータベースから呼び出されるライブラリ関数を使用してこれを実行したくありません。

どうして?あなたはDLL Hellに相当するデータベースに向かいます。

互換性のないバージョン

... Windows 2000より前のバージョンでは、COMクラステーブルがすべてのユーザーとプロセスで共有されていたため、Windowsはこれに対して脆弱でした。1つのDLL / EXE内の1つのCOMオブジェクトのみが、システム上で特定のグローバルCOMクラスIDを持つと宣言できます。プログラムがそのクラスのインスタンスを作成する必要がある場合は、現在中央に登録されている実装を取得しました。その結果、共通オブジェクトの新しいバージョンをインストールするプログラムをインストールすると、以前にインストールされていた他のプログラムが意図せず壊れることがあります。

.net 2.0アプリケーションを実行しているサーバーに.net 4.5をインストールするとどうなりますか?何もありません。アプリケーションは2.0フレームワークを引き続き使用します。3つのアプリケーションデータベースをホストしているサーバーでLastIndexOf関数を更新し(そのうちの1つへのアップグレードの一部として)、何が起こりますか?3つすべてが最新バージョンを使用しています。

別の方法は、SQL#で採用されているアプローチです。これは各ユーザーデータベースのスキーマにインストールされるため、Application-Yの安定性を危険にさらすことなく、Application-Xのデータベースを安全にアップグレードできます。

厳しく管理された変更管理環境で作業している場合、選択の余地はありません。コンポーネントのすべてのコンシューマーをテストしないと、共有コンポーネントをアップグレードできません。もう少し「速くて緩い」場所で作業している場合は、パッチ/アップグレードで意図せず何かを壊す可能性があります。


あなたが反論を望んでいるようだったので、反論を述べさせてください。:-)(1)問題のデータベースのセットはすべて関連しており、完全に異なるアプリケーションの一部ではないと想定しました。(2)この場合LastIndexOf、変更するように呼び出された関数には多くの危険性があるとは思いません。一部のアプリ/データベースのみを破壊するような方法では、はるかに危険です。これは、CLRや、複数のアプリにサービスを提供する真に中心的で複雑な機能にとっては大きな問題だと思います。(3)私の実際の好みは、単純なタスクでは関数をまったく使用しないことです。
アーロンバートランド

1
もちろん、いつもあなたの考えを歓迎します:)
Mark Storey-Smith

ちょっと、そこ。SQL#の作成者として、私は前向きな言及に感謝します :-)。ただし、すべてのSQL#オブジェクトに個別のスキーマを使用する主な決定点は、SQL#がインストールされている場所に関係なく名前の競合が発生しないように名前空間を作成することであることを明確にする必要があります。それでも、アプリの構造に応じて、バージョニングに関して考慮する必要があるポイントを提示します。個人的には、Utility一般にライブラリと呼ばれるもののDBを用意するのが好きですが、少しリスクが高くなり、徹底的なテストが必要になります。
ソロモンルツキー2016年

0

この質問に対する答えは、T-SQLオブジェクトとSQLCLRオブジェクトのどちらで話しているかによって異なります。SQLCLRオブジェクトを処理するときに考慮する必要のあるさまざまな(さらに多くの)要因があります。

T-SQLオブジェクトに関して、ここでの両方の答えは有効なポイントをもたらします。@Aaronの回答で説明されているように、中央DBは非常に便利です。シノニムを使用すると、共有リソースを指すDBや、ローカルリソースを使用するDBを簡単に作成できます。しかし、より強い依存によるリスクの増大に関するマークの回答で指摘された点は無視できません。

ただし、SQLCLRオブジェクトを処理している場合は、まず、以下の回答で取り上げたすべてのポイントを考慮する必要があります。

パフォーマンスの観点からCLR関数をより適切に使用する方法(各DB内で繰り返すか、一般的な関数を使用する)?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.