64

何百もの厄介な名前のテーブル (CG001T、GH066L など) を含むデータベースがあり、それぞれに「わかりやすい」名前のビューがあります (たとえば、ビュー「CUSTOMERS」は「SELECT * FROM GG120T」です)。 . ビューに "WITH SCHEMABINDING" を追加して、ビューにインデックスを付けることができるなど、それに関連するいくつかの利点を得ることができるようにしたいと考えています。

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

4

10 に答える 10

49

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

于 2009-11-02T14:18:18.133 に答える
34

ああ、SCHEMABINDINGの使用には間違いなく欠点があります。これらは、特に COMPUTED 列と組み合わせると、SCHEMABINDING に由来し、関係をロック」し、いくつかの「些細な変更」をほぼ不可能にします。

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

それを頑張ってください!

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

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

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

于 2013-07-02T01:41:24.237 に答える
33

まったくありません。より安全です。どこでも使用しています。

于 2009-11-02T09:30:18.137 に答える
6

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

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

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

于 2013-03-06T03:50:42.643 に答える
4

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

更新/アップグレードの前にスキーマバインディングなしでビューを変更してから、元に戻す必要があります。他の人が言及したように。計画や規律などが必要です。

于 2009-11-03T03:32:04.843 に答える
2

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

名前 'table' はスキーマ バインディングに対して無効であるため、ビュー 'view' をスキーマ バインドできません。名前は 2 部構成である必要があり、オブジェクトはそれ自体を参照できません。

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

not null 制約を追加すると、列のデータ型を強制的に上書きする方法に少し似ています-厄介です!

また、変更したいスキーマにバインドされたオブジェクトに依存する他のビューまたはプロシージャを再定義する必要があります...これは、追加するためだけに関数とビューの大規模なカスケードを再定義する(そしておそらく壊す)必要があるかもしれないことを意味します(例えば) 1 つの列に対する非 null 制約。

個人的には、これは実際には解決策ではなく、データベースの変更が自動的に適用される適切なプロセスを持つ方が良いと思います。データベースを変更することは悪夢ではありません. そうすれば、テーブルに変更を適用するときのプロセスの一部として、すべてのビューと関数を削除して最初から再作成することができます (とにかく作成時にチェックされます)。

于 2014-04-09T09:13:29.527 に答える
1

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

于 2016-02-19T16:43:27.830 に答える
1

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

于 2016-02-17T12:01:22.293 に答える
1

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

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の質問は関連しています。

于 2015-03-04T15:24:38.433 に答える
0

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

于 2016-11-10T08:08:39.993 に答える