17

データベース内のトリガーまたは制約でビジネス クリティカルなロジックを使用する必要があるかどうかを調べようとしています。
これまでのところ、トリガーにロジックを追加しました。これにより、次に何が起こるかを制御できるようになり、ユーザーを混乱させる可能性のあるエラーの代わりにカスタム ユーザー メッセージを提供できるようになります。

トリガーよりも制約を使用することで顕著なパフォーマンスの向上はありますか?また、使用するものを決定するためのベスト プラクティスは何ですか?

4

12 に答える 12

15

制約が受け継がれます!

  • 制約を使用して、リレーショナル原則、つまりデータに関するファクトを指定します。いくつかの事実が変更されない限り(つまり、新しい要件)、制約を変更する必要はありません。

  • トリガーを使用して、データの処理方法(挿入、更新など)を指定します。これは、物事を行うための「非リレーショナル」な方法です。

例えで自分自身をよりよく説明するために:SQLクエリを書く適切な方法は、「取得方法」ではなく「必要なもの」を指定することです。RDBMSにそれを行うための最良の方法を見つけさせてください。ここでも同じことが当てはまります。トリガーを使用する場合は、実行の順序、カスケードなど、さまざまなことを覚えておく必要があります。可能であれば、SQLに制約を付けて実行させます。

それは、トリガーに用途がないということではありません。データに関する事実を指定するために制約を使用できない場合があります。しかし、それは非常にまれです。それが頻繁に発生する場合は、スキーマに問題がある可能性があります。

于 2008-09-29T10:25:39.483 に答える
13

ベスト プラクティス: 制約を使用して実行できる場合は、制約を使用します。

トリガーは、(正しく使用されていれば)信用を失うほど悪くはありませんが、可能な限り常に制約を使用します。最新の RDMS では、トリガーのパフォーマンス オーバーヘッドは制約に匹敵します(もちろん、誰かがひどいコードをトリガーに配置できないわけではありません!)。

テーブルの 2 つの外部キー フィールドの 1 つだけを入力するように強制したい場合など、「複雑な」制約を強制するためにトリガーを使用する必要がある場合があります (いくつかのドメイン モデルでこの状況を見てきました)。

ビジネス ロジックを DB ではなくアプリケーションに配置するかどうかの議論は、環境によってある程度異なります。DB にアクセスするアプリケーションが多数ある場合、制約とトリガーの両方が、データが正しいことを最終的に保護する役割を果たします。

于 2008-09-29T10:10:27.663 に答える
7

制約を使用する他の理由に加えて、Oracle オプティマイザーは制約を有利に使用できます。

たとえば、次のような制約が(Amount >= 0)あり、Oracle でクエリを実行するとWHERE (Amount = -5)、一致する行がないことがすぐにわかります。

于 2008-11-12T23:01:03.350 に答える
7

トリガーは、パフォーマンスの問題に発展する可能性があります。それが起こるのとほぼ同時に、メンテナンスの悪夢にもなりました。何が起こっているのか把握できず (おまけに!) アプリケーションは「偽の」データの問題で不規則に動作します。[本当に、それらはトリガーの問題です。]

エンド ユーザーが直接 SQL に触れることはありません。アプリケーション プログラムを使用します。アプリケーション プログラムには、トリガーよりもはるかにスマートで保守しやすい方法でビジネス ロジックが含まれています。アプリケーション ロジックをアプリケーション プログラムに入れます。データベースにデータを入れます。

あなたとあなたの「ユーザー」が共通の言語を共有していない限り、制約違反を説明することができます。別の方法 (説明はありません) は、単純なデータベースを問題に変えます。なぜなら、データとアプリケーション コードが混同されて保守不可能な泥沼になるからです。

「誰もがデータモデルを正しく使用しているという絶対的な保証を得るにはどうすればよいでしょうか?」

2 つ (半) のテクニック。

  1. モデルが正しいことを確認してください。実際の問題領域と一致しています。複雑な手を振っている説明、ストアド プロシージャ、およびトリガーによってのみ整理できるハック、回避策、またはショートカットはありません。

  2. アプリケーションのビジネス モデル層を定義するのに役立ちます。誰もが共有して再利用するアプリケーション コードの層。

    を。また、モデル層が人々のニーズを満たしていることを確認してください。モデル レイヤーに適切なメソッドとコレクションがあれば、それをバイパスして基になるデータに直接アクセスするインセンティブは少なくなります。一般に、モデルが正しければ、これは深刻な問題ではありません。

トリガーは、起こるのを待っている列車事故です。制約はそうではありません。

于 2008-09-29T10:02:10.677 に答える
5

制約とトリガーは、2 つの異なるもののためのものです。制約は、データのドメイン (有効な入力)を制約するために使用されます。たとえば、SSN は char(9) として格納されますが、[0-9][0-9][0-9][0-9][0-9][0-9][ という制約があります。 0-9][0-9][0-9] (すべて数値)。

トリガーは、データベースにビジネスロジックを適用する方法です。SSN をもう一度取り上げます。おそらく、SSN が変更されるたびに監査証跡を維持する必要があります。これは、トリガーを使用して行われます。

一般に、最新の RDBMS におけるデータ整合性の問題は、制約のバリエーションで処理できます。ただし、不適切な正規化 (または要件の変更により不適切な正規化が行われる) によって制約が妨げられる場合があります。その場合、トリガーは制約を強制できる可能性がありますが、RDBMS に対して不透明であるため、最適化には使用できません。これは「隠された」ロジックでもあり、メンテナンスの問題になる可能性があります。スキーマをリファクタリングするかトリガーを使用するかの決定は、その時点での判断です。

于 2008-09-29T11:04:29.873 に答える
4

一般的に言えば、私は制約を好み、私のコードはSQLサーバーのエラーをキャッチして、ユーザーにとってより使いやすいものを提示します.

于 2008-09-29T09:59:30.420 に答える
3

@onedaywhen

SQL Serverで制約としてクエリを使用できます。クエリをスカラー関数に適合させる必要があります:http://www.eggheadcafe.com/software/aspnet/30056435/check-contraints-and-tsql。 aspx

于 2008-10-01T21:43:42.347 に答える
2

@Mark Brackett: 「制約はドメインを制約するために使用されます... トリガーはビジネス ロジックを強制する方法です」: SQL Server ではそれほど単純ではありません。制約の機能が制限されているためです。たとえば、まだ完全な SQL-92 ではありません。テンポラル データベース テーブルのシーケンス化された「主キー」の古典的な例を見てみましょう。理想的には、サブクエリで CHECK 制約を使用して、同じエンティティの期間が重複しないようにしますが、SQL Server ではそれができないため、引き金。また、SQL Server には、制約のチェックを延期する SQL-92 機能がありませんが、代わりに (実際には) SQL ステートメントごとにチェックされるため、SQL Server の制限を回避するにはトリガーが必要になる場合があります。

于 2008-09-29T13:58:28.253 に答える
2

可能であれば、制約を使用してください。彼らはわずかに速くなる傾向があります。トリガーは、制約では処理できない複雑なロジックに使用する必要があります。トリガーの書き込みも同様に注意が必要です。トリガーを作成する必要がある場合は、セット ベースのステートメントを使用してください。その上で!)、一度に 1 つのレコードだけではありません。回避できる場合は、トリガーでカーソルを使用しないでください。

トリガーまたは制約の代わりにアプリケーションにロジックを配置するかどうかについて。そんなことしたらダメ!!!はい、アプリケーションはデータを送信する前にチェックを行う必要がありますが、データの整合性とビジネス ロジックはデータベース レベルである必要があります。そうしないと、複数のアプリケーションがデータに接続したり、グローバルな挿入がアプリケーションの外部で行われたりしたときに、データが台無しになります。データ整合性はデータベースにとって重要であり、データベース レベルで実施する必要があります。

于 2008-09-29T13:21:04.537 に答える
1

@Meff: 関数を使用するアプローチには潜在的な問題があります。簡単に言えば、SQL Server CHECK 制約は作業単位として単一の行で設計されており、結果セットで作業するときに欠陥があるためです。詳細については、[ http://blogs.conchango.com/davidportas/archive/2007/02/19/Trouble-with-CHECK-Constraints.aspx][1]を参照してください。

[1]: David Portas のブログ: CHECK 制約に関するトラブル。

于 2008-10-02T10:11:03.050 に答える
0

制約については、ここにいる全員に同意します。できるだけそれらを使用してください。

特に新しい開発者では、トリガーを使いすぎる傾向があります。トリガーが別のトリガーを起動し、別のトリガーが最初のトリガーを繰り返す別のトリガーを起動し、サーバーを拘束するカスケード トリガーを作成する状況を見てきました。これはトリガーの非最適なユーザーです ;o)

そうは言っても、トリガーにはその場所があり、適切な場合に使用する必要があります。それらは、データの変更を追跡するのに特に適しています (Mark Brackett が述べたように)。「ビジネス ロジックをどこに配置するのが最も理にかなっているのか」という質問に答える必要があります。ほとんどの場合、それはコードに属していると思いますが、心を開いておく必要があります。

于 2008-09-29T13:00:54.353 に答える