web-dev-qa-db-ja.com

SQL Serverの「WITH SCHEMABINDING」のマイナス面は?

数百の厄介な名前のテーブル(CG001T、GH066Lなど)を含むデータベースがあり、「フレンドリ」な名前のビューがあります(ビュー「CUSTOMERS」は「SELECT * FROM GG120T」など)。 。いくつかのビューには計算列があり、その場で計算するのに費用がかかるため、ビューに "WITH SCHEMABINDING"を追加して、ビューにインデックスを付けることができるなど、それに関連するいくつかの利点を得ることができます。

これらのビューをSCHEMABINDINGすることの欠点はありますか?欠点を漠然と暗示する記事を見つけましたが、詳細には触れません。ビューがスキーマにバインドされると、最初にビューをドロップせずにビューに影響を与えるもの(たとえば、列のデータ型や照合順序)を変更できないことを知っています。ビュー自体にインデックスを付ける機能は、スキーマの変更をより慎重に計画することのマイナス面をはるかに上回るようです。

58
SqlRyan

全然ない。より安全です。どこでも使用します。

27
gbn

最初にビューをドロップしない限り、テーブルを変更/ドロップすることはできません。

44
Dan S

ああ、DEFINITELY DOWNSIDES SCHEMABINDINGを使用するためにあります-これらは実際にはSCHEMABINDINGに由来し、特にCOMPUTED列と組み合わせた場合は"LOCKS" THE RELATIONSHIPSであり、いくつかの「些細な変更」がありますほぼ不可能。

  1. テーブルを作成します。
  2. SCHEMABOUND UDFを作成します。
  3. UDFを参照するCOMPUTED PERSISTED列を作成します。
  4. 上記の列にINDEXを追加します。
  5. UDFを更新してください。

頑張ってください!

  1. UDFはSCHEMABOUNDであるため、ドロップまたは変更できません。
  2. COLUMNはINDEXで使用されているため、削除できません。
  3. COLUMNはCOMPUTEDであるため変更できません。

まあ、フラク。本当に..!?!私の一日はピタになりました。 (現在、ApexSQL Diffのようなツールは、変更されたスキーマが提供されている場合、このを処理できますですが、問題はここでスキーマを変更することすらできないことです!)

私はSCHEMABINDINGに反対ではありません(この場合はUDFに必要です)が、「一時的に無効にする」方法(見つけられる)がないことに反対ですSCHEMABINDING

31
user2246674

これらのテーブルがサードパーティアプリからのものである場合(テーブルを非表示にしようとすることで有名です)、これらのテーブルのいずれかを変更しようとすると、アップグレードが失敗します。

更新/アップグレードの前にスキーマをバインドせずにビューを変更し、元に戻すだけです。他の人が言及したように。いくつかの計画、規律などが必要です。

4
JeffO

1つの欠点は、ビューをスキーマバインドした場合、他のスキーマにバインドされたビューしか参照できないことです。

これは、ビューをスキーマバインドしようとしましたが、参照する他のビューの1つもスキーマバインドされていないため、スキーマバインドできないことを通知するエラーメッセージが表示されたためです。

これの唯一の結果は、新しいまたは既存のビューを参照するために、スキーマにバインドされたビューを突然更新したい場合、その新しいまたは既存のビューもスキーマバインドする必要がある場合があることです。その場合、ビューを更新することができなくなり、データベース開発者がスキーマバインドビューを操作する方法を知っていることを望みます。

4
Triynko

もう1つの欠点は、すべてにスキーマ修飾名を使用する必要があることです。次のようなエラーメッセージが大量に表示されます。

ビュー 'view'をスキーマバインドできません。名前 'table'はスキーマバインドに無効です。名前は2つの部分からなる形式である必要があり、オブジェクトはそれ自体を参照できません。

また、スキーマバインディングを「スイッチオフ」するには、ビューを変更します。これにより、ビューの選択ステートメントを再定義する必要があります。再定義する必要がないのは、助成金だけだと思います。ビューを上書きすることは本質的に安全でない操作のように思えるので、これは私を大いに先送りにします。

Nullでない制約を追加する方法に少し似ているため、列のデータ型を上書きする必要があります-厄介です!

また、変更するスキーマバインドオブジェクトに依存する他のビューまたはプロシージャを再定義する必要があります。これは、追加するだけで関数やビューの大きなカスケードを再定義(および場合によっては分割)する必要があることを意味します。 )1つの列に対する非NULL制約。

個人的には、これは実際にソリューションを表すものではなく、データベースの変更が自動的に適用されるため、データベースを変更するのは悪夢ではない、まともなプロセスを持つ方が良いと思います。そうすることで、テーブルに変更を適用する際のプロセスの一部として、すべてのビューと関数を削除し、最初から再作成することができます(作成時にチェックされます)。

2
JonnyRaa

これは私にとってマイナスのように思えます(#は私のものです):

Cannot create index on view "###.dbo.###" because it uses a LEFT, RIGHT, or FULL OUTER join, and no OUTER joins are allowed in indexed views. Consider using an INNER join instead.

LEFTに参加する必要があります。 これSO質問 は関連しています。

1
ZagNut

SQL Svr 2005以来、このベストプラクティスを上回るマイナスの影響はほとんどありません。恐ろしいテーブルスプールを回避します。私にとって大きなマイナス点は、スキーマにバインドされたsproc、funcs、viewsにmaster dbなどの「外部」データベースを含めることができないため、実稼働コアなどがない限り、すべての優れたリアルタイムシステムをゴミ箱に捨てることができることですデータベースはマスター内にあります。私にとっては、システムがなければ人生に対処することはできません。もちろん、すべての処理にスプールのないパフォーマンスが必要なわけではなく、高速および低速の結果をより高いデータクラスレイヤーで同時に組み合わせることができます。

1
thetempest

TSQLt単体テストフレームワークを使用すると、FakeTableメソッドを使用するときに問題が発生し、回避策が必要になります。これにより、スキーマバインドでビューにリンクされたテーブルを偽造することはできません。

1

お使いのツール(ssmsなど)がベースオブジェクトのスキーマ変更エラーを上手く/エレガントに処理しない場合、実際に混乱を引き起こす可能性があります。それは私が今座っていることであり、これはフリンジケースであることを理解しています

0
Adriaan Davel