web-dev-qa-db-ja.com

SQLトリガーと、いつ使用するか、または使用しない場合。

私が最初にSQLについて学んでいたとき、私はいつも言われていました。本当に必要な場合にのみトリガーを使用し、可能であれば代わりにストアドプロシージャを使用することを選択しました。

今は残念なことに(数年前の良い)当時、私は今ほどファンダメンタルズに興味があり、気にしていなかったので、その理由を尋ねることはありませんでした。

これについてのコミュニティの意見は何ですか?それは誰かの個人的な好みにすぎませんか、それとも正当な理由がない限り、トリガーは(カーソルのように)回避する必要がありますか?.

43
John Mitchell

データベーストリガーに関するウィキペディアの記事 は、トリガーとは何か、さまざまなデータベースでトリガーを使用するタイミングについての概要を示しています。

以下の説明は、SQL Serverのみに基づいています。

トリガーの使用が正当化される場合、トリガーの使用は非常に有効です。たとえば、すべてのテーブルのすべてのCRUDコマンドで明示的な手続きコードを必要とせずに、監査(データの履歴を保持)に優れた価値があります。

トリガーを使用すると、データが変更される直前とデータが変更された直後に制御できます。これにより、次のことが可能になります。

  • 前述の監査
  • 必要に応じて、検証とビジネスセキュリティチェックを行います。このタイプのコントロールにより、データベースへの挿入の前後に列のフォーマットなどのタスクを実行できます。

私は常に言われていましたが、本当に必要な場合にのみトリガーを使用し、可能であれば代わりにストアドプロシージャを使用することを選択しました。

これにはいくつかの理由が考えられます。

  1. 以前はトリガーを使用していた一部の機能を、合計の更新や列の自動計算など、他の方法で実行できるようになりました。
  2. コードが存在することを知らずにコードを調べても、トリガーがどこで呼び出されるかはわかりません。データの変更を確認すると、その影響がわかります。トリガーが存在するか、テーブルに作用していることがわからない限り、変更が発生した理由を理解するのが難しい場合があります。
  3. 複数のテーブルでCHECK、RI、トリガーなどの複数のデータベースコントロールを使用する場合、トランザクションの詳細なフローを理解して維持するのは複雑になります。いつ何が起こるかを正確に知る必要があります。この場合も、適切なドキュメントが必要です。

トリガーストアドプロシージャと非トリガーストアドプロシージャの違いは次のとおりです。

  • 非トリガーストアドプロシージャは、コード、スケジューラー、またはバッチジョブなどから明示的に呼び出さなければならないプログラムに似ていますが、トリガーは特別な種類のストアドプロシージャであり、ユーザーが直接実行するのではなく、イベントの応答。イベントは、たとえばデータ列のデータの変更である場合があります。
  • トリガーにはタイプがあります。 DDLトリガーとDMLトリガー(タイプ:INSTEAD OF、For、AFTER)
  • 非トリガーストアドプロシージャは、任意のタイプのオブジェクトを参照できますが、ビューを参照するには、INSTEAD OFトリガーを使用する必要があります。
  • SQLServerでは、トリガー以外のストアドプロシージャに任意の数を設定できますが、テーブルごとに1つのINSTEAD OFトリガーしか使用できません。
32
NoChance

トリガーは、複雑なデータ整合性ルールの要件です。これらは、データベース以外の場所には適用できません。そうしないと、データの整合性の問題が発生します。

また、データベースに対するすべての変更をキャプチャしたくない場合(アプリケーションからの監査の問題)を除いて、監査に最適な場所です。

トリガーは、注意深く書かれていなければ、パフォーマンスの問題を引き起こす可能性があり、十分な開発者がそれらをうまく書くのに十分な知識を持っていません。これは彼らが彼らの悪いラップを得るところの一部です。

多くの場合、トリガーはデータの整合性を維持する他の方法よりも遅いため、チェック制約を使用できる場合は、トリガーの代わりにそれを使用します。

電子メールを送信しようとするような愚かなことをする悪いトリガーを書くのは簡単です。電子メールサーバーがダウンした場合、データベースのレコードを変更できないようにしますか?

SQLサーバーでは、トリガーはレコードのバッチに対して動作します。開発者は、1つのレコードの挿入、更新、または削除を処理するだけでよいと考えることがよくあります。データベースに発生するデータ変更の種類はこれだけではありません。すべてのトリガーは、1レコードの変更と多数のレコードの変更の条件下でテストする必要があります。 2番目のテストの実行を忘れると、トリガーのパフォーマンスが著しく低下したり、データの整合性が失われたりする可能性があります。

10
HLGEM

データベーストリガーの使用

  1. 列の値を自動的に駆動します。
  2. 複雑な整合性制約を実施するため。
  3. 複雑なビジネスルールを適用するため。
  4. 複雑なセキュリティ認証をカスタマイズします。
  5. レプリケートテーブルを維持するため。
  6. データの変更を監査する。
4
asha

私が個人的に遭遇したもう1つの使用例は、複数のプログラムによってアクセスされるデータベースの場合です。機能を実装したいがすべてのシステムを再設計したくない場合は、トリガーが賢明な解決策になります。

たとえば、私は最近、以前は単なるオフィスシステムとして存在していたデータベースに取り組みました。 Webアプリケーションがそれとインターフェースするように作成されたとき、トランザクション処理などの複数のイベントによって起動される通知システム(たとえば、stackexchangeと同様)を実装したいと考えました。トリガーを実装して、オフィスのバックエンドでの更新がトリガーを発してフロントエンドの通知を作成し、トランザクションがオフィスで処理されたことをユーザーに知らせることができました。

2
Matt

トリガーを使用して、データベーススキーマの作成やDMLステートメント中には適用できないデータベースに制約を適用できます。

1
DEEPAK JADGE

ほぼリアルタイムでデータをサードパーティのシステムにプッシュする必要があるとしましょう。テーブルには950ギガバイトのデータが含まれているため、単純にテーブル全体をサードパーティアプリにプッシュするだけでは大きすぎます。

代わりに、変更をキューに蓄積します。いくつかの外部プログラムは、キューに入れられたデータの小さなバッチを定期的に押し出します。

システムには2000を超えるストアドプロシージャがあります。また、ソースコードに大量のSQLが存在することも知っています。キューが正しく設定されていることを保証するには、保存されているすべてのプロシージャとコードを検索し、何も見落とさないようにする必要があります。

代わりに、テーブルにトリガーを配置して、キューを最新の状態に保つことができます。何も見逃さないことが保証されています。 1つの中心的な場所。パフォーマンスのペナルティ?トリガーによるものであろうと外部によるものであろうと、キューにデータを追加することによるヒットを回避できないからではありません。

このシナリオでは、トリガーを使用しないことは設計上の選択として不適切です。後でデータをプッシュする新しい方法(たとえば、キュ​​ーが機能していないなど)を使用する場合、トリガーを使用すると、インターフェイスの変更が保護されます。多くの場合、トリガーが最良の選択です。独断的な反トリガーのファンボーイに耳を傾けないでください。

0
Lord Tydus