web-dev-qa-db-ja.com

他のデータベースの内部ストアドプロシージャを使用するための中央CLRストアドプロシージャ/関数リポジトリライブラリを設定しますか?

C#CLRで開発したコードをシステム上のすべてのデータベースで使用するために使用します。これにより、それぞれを信頼できるように設定してCLRをオンにし、同じコードの束を各データベース内に保持する必要がなくなります。 。

管理とセキュリティの観点からこれを行う最善の方法はありますか? CLR関数は、文字列ブレーカー、電子メール検証、url en/decode、base64などのように非常に基本的です。各データベースのdboスキーマのみが関数にアクセスできるようにしたいと思います。

  1. これを行う簡単な方法はありますか?
  2. また、CLR dllが埋め込まれているかどうか、データベースを移動するとタグが付いているかどうか、またはDLLも移動する必要があるかどうかもわかりません。

ありがとう

17
Alex Erwin

私たちの会社では、その正確なセットアップがあります。 CLRアセンブリを作成すると、それを作成したデータベース内にアセンブリのバイナリ表現が保存されます。これにより、いつでもデータベースを移動した場合に、アセンブリを持ち出すことができます(スクリプトを作成することもできます)。

数か月前のデータセンターが浸水し、数台のサーバーが水で一杯になりました。私がそれらを再構築したとき、私は前夜に取られたデータベースのバックアップのみを使用しました。これまでのところ問題はありません..(木に触れてください!)

これがセキュリティの観点から正しいことかどうかはわかりませんが、CLRプロシージャなどへのアクセスを許可する方法は、共有データベース内にロールを作成し、他のデータベースからそのロールにユーザーを追加することです。次に、CLRプロシージャでの実行が許可されます。

CLRが含まれているデータベース外のリソースへのアクセスなどをCLRが行おうとすると、アクセスの問題が発生する可能性がありますが、アセンブリを作成するときにアセンブリにアクセス許可を設定できます。以下のリンクには、ここで説明できるよりも多くの権限に関する情報があります。

http://msdn.Microsoft.com/en-us/library/ms345101.aspx

これがお役に立てば幸いです。

8
Mr.Brownstone

アセンブリバイナリはblobとしてデータベースに格納されるため、データベースのどこにでも持ち運びできます。 CLRはインスタンスでのみ有効です-そのためのデータベース固有の設定はありません。

とにかく、なぜこれをやろうとしているのですか?

(私は議論をするつもりはありません。おそらくあなたのニーズを満たす別の方法で問題を解決できるので、関係する動機を聞きたいだけです。)


アセンブリを共有データベースに配置する以外に、これを簡単に行う方法はありません。

とは言え、集中化する非常に説得力のある理由がある特定の状況がない限り、データベース中心のアーキテクチャを採用することが有利だと思います。理由は、アセンブリ(またはそのことについては何か)をデータベースの外部に配置すると、環境に依存関係が作成されるためです。これは、SQL Server 2012以降、Microsoftが包含データベースを構築しようとしている反対のアプローチです。

  • レプリケーションやクラスタリングなどの機能を使用する必要が生じた場合、この依存関係により、デプロイメントが非常に複雑になる可能性がありますが、トラブルシューティングやフェイルオーバーの手順も複雑になる可能性があります。

  • このアーキテクチャは、システムに不慣れな人にとってはあまり明白ではありません(つまり、自己発見が難しく、自己文書化が少なくなります)。

  • さまざまなデータベースでさまざまなセキュリティを必要とする場合や、変動を伴うものを必要とする場合は、危害を加えることになります。

  • これらのデータベースが顧客に配備される場合(そうではないようですが、完全を期すためにこれを言います)、これにより、配備手順、保守、およびトラブルシューティングが複雑になります。

  • すべてのデータベースがこのコードを共有するため、バグが導入(または修正)された場合、データベースに依存するアプリケーションallが壊れる可能性があります。包括的な単体テストは絶対に必要です。

同じ機能を必要とする複数のデータベースがある場合、関連する重複の量を削減する他の方法があります。これが演習のポイントだと思います。かなり複雑なCLRアセンブリでも、データベース自体(ほとんどの場合)のデータと比較して物理的な記憶域をあまり占有しないため、これを必要とする数千の小さなデータベースがない限り、これは有効な引数とは見なされません。アセンブリ。

実行できることは、これらのデータベースの展開手順の他の部分を変更して、ソースの重複を減らすことです。たとえば、ソース管理のCLRコードの共通の場所からアセンブリをビルドして展開します。または、同じアセンブリをデータベースに展開するスクリプトを作成します。物事のこの部分を可能な限り自動化し、それは大したことではありません。

私が提案しているのはトレードオフであることに同意します。これは、まだ重複があるためですが、それは、規定された標準に従わないアーキテクチャの実装に伴う欠点とバランスを取る必要があります。自分の環境に何が適切かを決めることができるのはあなただけです。

6
Jon Seigel

他の2つの答えが正しく述べているように、アセンブリは特定のデータベースに読み込まれ、システム全体ではありません(ただし、Assembly_idの値isシステム全体で一意であることはかなり確実です)。これは、それらがロードされた各データベースとともにバックアップおよび復元されることを意味します。

また、CLR Integrationenabled/disabled設定(sp_configureを使用)isシステム全体。補足として、この設定はser-created CLR機能専用です。一般的な意味でのCLRは、特定の組み込み機能がそれに依存するため、常に有効になっています。

とはいえ、ここでの他の2つの答えは有効な点を示していますが、それらの点はSQLCLR固有ではなく、SQLCLRコードに固有のこの決定を行う際の要因についての言及はありません。個々のデータベースにデータベースをデプロイする場合(多くのデータベースがある場合)、考慮すべきメモリの問題、潜在的なリソース競合の問題、潜在的なセキュリティ関連の問題などがあります。

集中データベースと個々のデータベースのどちらを配置するかを決定する際に、特にSQLCLRコードについて覚えておくべきことの包括的なリストを提供しました。ここにリストを複製するのではなく、次の回答を参照してください(これもDBA.SEにあります)。

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

また、関連するノートで、なぜデータベースがTRUSTWORTHY ONに設定されているのか疑問に思います。質問に記載されている機能(つまり、「文字列ブレーカー、電子メール検証、url en/decode、base64など」)は、SAFEアセンブリ内ですべて可能です。絶対に必要な場合を除き、EXTERNAL_ACCESSまたはUNSAFEのperission_set値を使用しないでください。そして、いくつかの関数が必要な場合、それらはSAFEコードのみを含む別のアセンブリにある必要があります。これにより、データアクセスを行わないスカラー関数andIsDeterministic = trueとしてマークされるようになります。並列プランに参加できるというパフォーマンス上の利点を活用するため。

1
Solomon Rutzky