データベースは悪い考えを引き起こしますか?
私の経験では、それらは意外な副作用を引き起こす可能性があり、デバッグが難しいため(特に、1つのトリガーが別のトリガーを起動した場合)、悪です。多くの場合、開発者はトリガーがあるかどうかを考えさえしません。
一方、常に新しいロジックが発生した場合、 FOO
データベースにが作成される場合は、FOOテーブルの挿入トリガーが最も確実な場所になります。
トリガーを使用するのは、の設定などの非常に単純な場合のみですModifiedDate
。
データベースは悪い考えを引き起こしますか?
私の経験では、それらは意外な副作用を引き起こす可能性があり、デバッグが難しいため(特に、1つのトリガーが別のトリガーを起動した場合)、悪です。多くの場合、開発者はトリガーがあるかどうかを考えさえしません。
一方、常に新しいロジックが発生した場合、 FOO
データベースにが作成される場合は、FOOテーブルの挿入トリガーが最も確実な場所になります。
トリガーを使用するのは、の設定などの非常に単純な場合のみですModifiedDate
。
回答:
トリガーの主な問題は
これは、適切な状況で慎重に使用する必要があることを意味します。私の経験では、これはリレーショナルインテグリティの問題に限定されます(宣言的に取得できるよりも細かい場合もあります)。通常、ビジネスまたはトランザクションの目的ではありません。YMMV。
いいえ、それらは実際には良いアイデアです。特定のトリガーに問題がある場合は、正しく実行していませんが、通常はトリガー自体の概念ではなく、実装に問題があることを意味します:-)。
トリガーは、DBMS固有のアクティビティを、それが属するデータベースの制御下に置くため、よく使用されます。DBMSのユーザーは、そのようなことを心配する必要はありません。データの整合性はデータベース自体にあり、それを使用するアプリケーションやユーザーにはありません。データベースに制約やトリガー、その他の機能がなければ、ルールを適用するのはアプリケーションに任され、1人の不正なまたはバグのあるアプリケーション/ユーザーがデータを破壊するだけです。
たとえば、トリガーがなければ、自動生成された列などの不思議なことは存在せず、列を選択するときに各行の関数を処理する必要があります。これは、DBMSのパフォーマンスを低下させる可能性が高く、挿入/更新時に自動生成された列を作成する方がはるかに優れています。
また、トリガーがないと、事前トリガーなどのデータルールがDBMSで適用されず、列が特定の形式になるようになります。これは、一般に単なる外部キーのルックアップであるデータ整合性ルールとは異なることに注意してください。
ツールは決して悪ではありません。これらのツールのアプリケーションは悪である可能性があります。
同意する。トリガーに関する問題は、トリガーではなく人です。調べること、検討すること、および物事を正しくチェックするコーダーの負担を増やすことはより多くなりますが、私たちの生活をよりシンプルにするためにインデックスを破棄することはありません。(悪いインデックスは悪いトリガーと同じくらい悪いものになる可能性があります)
(私の心の中で)トリガーの重要性は次のとおりです...-
すべてのシステムは常に
有効な状態にある必要があります-この有効な状態を強制するコードは一元化する必要があります(すべてのSPに記述されているわけではありません)
メンテナンスの観点から見ると、トリガーは有能なコーダーやジュニア/アマチュアの問題にとって非常に役立ちます。しかし、これらの人々は何らかの方法で学び、成長する必要があります。
それはあなたの作業環境にかかっていると思います。よく学んで信頼できる人がいるのですか?そうでない場合は、2つの選択肢があるように見えます。-
補正するために機能を失う必要があることを受け入れます。
必要があることを受け入れる-別の人またはより優れたトレーニングと管理が必要であることを受け入れる
彼らは厳しいように聞こえます、そして私は彼らがそうであると思います。しかし、それは私の心の中で、基本的な真実です...
トリガーは悪であるだけでなく、優れたデータベース設計に必要だと思います。アプリケーションプログラマーは、データベースはアプリケーションによってのみ影響を受けると考えています。彼らはしばしば間違っています。データの変更がどこから来たかに関係なくデータの整合性を維持する場合、トリガーは必須条件であり、一部のプログラマーは、独自のアプリケーション以外のものが何かに影響を及ぼしているとは考えられないため、それを回避するのは愚かです。有能なデータベース開発者であれば、トリガーを設計、テスト、またはトラブルシューティングすることは難しくありません。また、(私と同じように)トリガーを見てトリガーが予期しない結果を引き起こしていると判断することも難しくありません。spで参照していないテーブルにFKエラーがあるというエラーが発生した場合は、トリガーが問題を引き起こしていること、そして有能なデータベース開発者もそうであることを、私はそれについても考えずに知っています。アプリケーションにのみビジネスルールを配置することは、ルールが存在し、プロセスに違反していることを他の人が知らないため、私が不良データを発見した最大の原因です。データ中心のルールはデータベースに属し、トリガーはより複雑なルールを適用するための鍵となります。
some programmers are too ethnocentric to consider that something other than their prized application may be affecting things
主に、はい。
トリガーの難しさは、「背後で」何かを行うことです。アプリケーションを保守している開発者は、それがそこにあることを簡単に認識できず、気付くことなく、物事を台無しにする変更を加えることができました。
メンテナンス作業を追加するだけの複雑なレイヤーを作成します。
トリガーを使用するのではなく、ストアドプロシージャ/ルーチンは通常、同じことを行うように作成できますが、明確かつ保守可能な方法で行います。
トリガーは非常に強力で便利です。トリガーが問題の最良の解決策となるシナリオはいくつもあります。
また、非常に優れた「ハッキング」ツールでもあります。コードとデータベースの両方をすぐに制御できない状況がよくあります。コードの次のメジャーリリースまで2か月待たなければならない場合でも、データベースにパッチをすぐに適用できます。その後、テーブルにトリガーを配置して、いくつかの追加機能を実行できます。その後、コードのリリースが可能な場合は、必要に応じてこのトリガーを同じ機能のコード化されたバージョンに置き換えることができます。
結局のところ、何をしているのか分からなければ、すべてが「悪」です。トリガーを理解できない開発者がいるためだと判断することは、一部の人が運転できないために車が悪いと主張することと同じです...
トリガーには用途があります。ロギング/監査と「最終変更」日付の維持は、以前の返信で言及されている2つの非常に優れた用途です。
ただし、優れた設計の中心的な信条の1つは、ビジネスルール/ビジネスロジック/呼び出すものはすべて1か所に集中する必要があるということです。ロジックの一部を(トリガーまたはストアドプロシージャを介して)データベースに配置し、一部をアプリケーションに配置すると、その原則に違反します。両方の場所でロジックを複製すると、常に互いに同期しなくなるため、状況はさらに悪化します。
すでに言及されている「最小の驚きの原則」問題もあります。
トリガーは、適切に使用すると優れたツールになります。特に、変更の監査、要約テーブルへの入力などに適しています。
これで、他のトリガーを開始する1つのトリガーで「トリガー地獄」になる場合、それらは「悪」になる可能性があります。私はかつて、「フレックストリガー」と呼ばれるCOTS製品を扱っていました。動的SQL文字列が実行されるたびにコンパイルされるため、これらのトリガーはテーブルに格納されました。コンパイルされたトリガーは、ルックアップを実行し、そのテーブルに実行するflexトリガーがあるかどうかを確認してから、「flex」トリガーをコンパイルして実行します。理論的には、製品は簡単にカスタマイズできるので、これは本当にクールなアイデアのように聞こえましたが、実際には、実行する必要があるすべてのコンパイルのためにデータベースがかなり爆発していました...
ええ、そうです、あなたが自分のやっていることを見通したままにしておけば素晴らしいです。監査、要約、自動シーケンスなどの非常に単純なものである場合、問題はありません。テーブルの成長率と、トリガーがパフォーマンスに与える影響を覚えておいてください。
高レベルでは、トリガーには2つのユースケースがあります1
1)何かを「自動的に」起こすため。この場合、トリガーは副作用を引き起こし、実行された(プリミティブ)演算子の挿入、更新、または削除を想定して予期しない方法でデータを変更し、トリガーを起動させました。
ここでの一般的な合意は、トリガーは実際に有害であるということです。これらは、INSERT、UPDATE、またはDELETEステートメントのよく知られたセマンティクスを変更するためです。これら3つのプリミティブSQL演算子のセマンティクスを変更すると、SQLプリミティブを使用して操作したときに、予期したとおりに動作しないデータベーステーブルで後で作業する必要がある他の開発者を悩ませるでしょう。
2)データ整合性ルールを実施するために、宣言的に処理できるルール(CHECK、PRIMARY KEY、UNIQUE KEY、およびFOREIGN KEYを使用)以外のルール。この使用例では、トリガーが行うすべてのトリガーはQUERY(SELECT)データであり、INSERT / UPDATE / DELETEによって行われている変更が許可されているかどうかを確認します。宣言的制約が私たちにしてくれるように。この場合にのみ、私たち(開発者)が施行をプログラムしました。
後者のユースケースでトリガーを使用しても害はありません。
私はそれについてブログを書いています:http://harmfultriggers.blogspot.com
トリガーは、必要な機能を実現するための最も直接的な方法であるトリガーを常に使用する必要があると思う開発者と、絶対に使用しない開発者を知っています。それは2つの収容所の間の教義のようです。
ただし、私はMarkRに個人的に完全に同意します。(ほぼ)トリガーと機能的に同等のコードを常に記述できるため、より目立ち、保守が容易になります。
悪じゃない。彼らは実際にのようなものを簡素化します
1.レコードまたはデータベーススキーマへの変更のログ記録/監査
本番環境での変更をロールバックするトリガーをALTER TABLEに設定できます。これにより、偶発的なテーブルの変更が防止されます。
2.複数のデータベースにわたる参照整合性(主/外部キー関係など)の実施
ALTER TABLE
。
彼らは悪だと言うのは大げさですが、メッシュの原因となる可能性があります。1つのトリガーの起動によって他のトリガーが起動されると、それは本当に複雑になります。問題があるとしましょう:http : //www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html
トリガーを使用してOracleでビジネスロジックを実行することは、複数の同時実行の問題があるため、見かけよりも困難です。他のセッションがコミットするまで、他のセッションの変更は表示されません。
この回答は、特にSQL Serverに適用されます。(それは私が知らない他のRDBMSにも当てはまるかもしれませんが、答えとしてそれを与えることを望んだでしょうここではこれのまとまりとして閉じられました。)
これまでの回答のいずれにも言及されていない1つの側面は、セキュリティです。デフォルトでは、トリガーは、トリガーを起動させるステートメントを実行するユーザーのコンテキストで実行されるため、すべてのトリガーを確認しない限り、セキュリティ上の脅威が発生する可能性があります。
「トリガーのセキュリティの管理」という見出しの下のBOLに示されている例GRANT CONTROL SERVER TO JohnDoe ;
は、自分の権限をエスカレートするためにコードを含むトリガーを作成するユーザーのものです。
私はそれらは悪である可能性があると思いますが、開発中の他のものと同じくらい悪です。
私は実際にはあまり経験がありませんが、私が取り組んだ最近のプロジェクトで彼らを経験したので、この結論に至りました。彼らが抱えている問題は、ビジネスロジックがコードライブラリとデータベースのです。
私はそれをsprocsを使用する場合の同様の議論と見なします。多くの場合、SQLでビジネスロジックをデータベースに書き込むのが本当に上手な開発者がいる一方で、ビジネスロジックが他の場所にはない開発者がいます。
したがって、私の経験則は、プロジェクトの構造を調べることです。ビジネスロジックをデータベースに格納することが現実的であると思われる場合は、トリガーがあると便利です。