私が元々SQLについて学んでいたとき、私はいつも言われました。本当に必要な場合にのみトリガーを使用し、可能であれば代わりにストアドプロシージャを使用することを選択します。
残念ながら当時(数年前)、私は今ほどファンダメンタルズに興味がなく、その理由を尋ねることはありませんでした。
これに関するコミュニティの意見は何ですか?誰かの個人的な好みなのか、それとも正当な理由がない限り、トリガーは(カーソルのように)避けるべきなのか。
私が元々SQLについて学んでいたとき、私はいつも言われました。本当に必要な場合にのみトリガーを使用し、可能であれば代わりにストアドプロシージャを使用することを選択します。
残念ながら当時(数年前)、私は今ほどファンダメンタルズに興味がなく、その理由を尋ねることはありませんでした。
これに関するコミュニティの意見は何ですか?誰かの個人的な好みなのか、それとも正当な理由がない限り、トリガーは(カーソルのように)避けるべきなのか。
回答:
データベース・トリガーの上のWikipediaの記事示す良いのトリガーが何であるかの概要と、異なるデータベースにそれらを使用します。
以下の説明は、SQL Serverのみに基づいています。
トリガーの使用は、その使用が正当化される場合に非常に有効です。たとえば、すべてのテーブルのすべてのCRUDコマンドで明示的な手続きコードを必要とせずに、監査(データの履歴を保持する)に優れた価値があります。
トリガーを使用すると、データが変更される直前とデータが変更された直後に制御できます。これにより以下が可能になります。
私は常に言われました、本当に必要な場合にのみトリガーを使用し、可能であれば代わりにストアドプロシージャを使用することを選択します。
この理由のいくつかは次のとおりです。
トリガーと非トリガーストアドプロシージャの違いは次のとおりです。
トリガーは、複雑なデータ整合性ルールの要件です。これらは、データベース以外では強制できません。そうしないと、データ整合性の問題が発生します。
また、データベースへのすべての変更(アプリケーションからの監査の問題)をキャプチャしたくない場合を除き、監査に最適な場所です。
トリガーは、慎重に記述されていないとパフォーマンスの問題を引き起こす可能性があり、十分な開発者がそれらを適切に記述するのに十分な知識がありません。これは、彼らが悪いラップを得る場所の一部です。
トリガーは多くの場合、データの整合性を維持する他の手段よりも遅いため、チェック制約を使用できる場合は、トリガーの代わりにそれを使用します。
電子メールを送信しようとするような愚かなことをする悪いトリガーを書くのは簡単です。電子メールサーバーがダウンした場合、dbのレコードを変更できないようにしたいですか?
SQLサーバーでは、トリガーはレコードのバッチで動作します。開発者は、1つのレコードの挿入、更新、または削除のみを処理する必要があると考えることがよくあります。データベースに発生するデータの変更はこれだけではありません。すべてのトリガーは、1レコードの変更と多くのレコードの変更の条件下でテストする必要があります。2番目のテストを忘れると、トリガーのパフォーマンスが著しく低下したり、データの整合性が失われたりする可能性があります。
私が個人的に遭遇した別のユースケースは、複数のプログラムによってアクセスされるデータベースの場合です。機能を実装したいが、そのためにすべてのシステムを再設計したくない場合、トリガーは賢明なソリューションになります。
たとえば、私は最近、以前はオフィスシステムとしてのみ存在していたデータベースで作業しました。webappがインターフェイスとなるように記述されている場合、トランザクションの処理などの複数のイベントによって起動される通知システム(たとえば、stackexchangeと同様)を実装する必要がありました。オフィスのバックエンドの更新がトリガーを起動してフロントエンドの通知を作成し、ユーザーにトランザクションがオフィスで処理されたことを知らせるトリガーを実装することができました。
トリガーを使用して、データベーススキーマの作成中およびDMLステートメント中に適用できないデータベースに制約を適用できます。
ほぼリアルタイムでデータをサードパーティシステムにプッシュする必要があるとしましょう。テーブルには950ギガバイトのデータが含まれているため、単純にテーブル全体をサードパーティアプリにプッシュするには大きすぎます。
代わりに、変更をキューに蓄積します。その後、一部の外部プログラムは、キューに入れられたデータの小さなバッチを定期的にプッシュします。
システムには2000以上のストアドプロシージャがあります。また、ソースコードには大量のsqlが存在することも知っています。キューが正しく読み込まれるようにするには、保存されているすべてのprocとコードを検索し、見逃さないようにする必要があります。
代わりに、キューを最新の状態に保つためにテーブルにトリガーを配置できます。何も見逃さないことが保証されています。1つの中央の場所。パフォーマンスの低下?トリガーによるものであれ、外部によるものであれ、キューを埋めるヒットが避けられないからではありません。
このシナリオでは、トリガーを使用しないことは設計上の悪い選択です。後でデータをプッシュする新しい方法(キューが機能しないなど)を使用したい場合、トリガーを使用するとインターフェースが変更されます。多くの場合、トリガーが最良の選択です。独断的なアンチトリガーファンボーイを聴かないでください。
電子メールを送信するトリガーは、必ずしも「愚かな」アイデアではありません。馬鹿げているのは、設計での電子メールの停止を予期せず、データ損失なしでそれを適切に処理することではありません。これの「愚かな」部分は、間違いを犯すのを免れていると感じる怠け者の開発者による、存在しないエラー処理にとって本当に悪いことです。
また、任意の複雑さを持ち、複数のトリガーまたは他のストアドプロシージャで再利用できるストアドプロシージャ/関数を呼び出すことで、トリガーをシンプルに保つことができるという観察を提供します。それがパッケージとライブラリがある理由です。
偏見は本当に不自由です。