200

データベーストリガーは悪い考えですか?

私の経験では、それらは驚くべき副作用を引き起こす可能性があり、デバッグが難しいため(特に、あるトリガーが別のトリガーを起動する場合)、悪です。多くの場合、開発者はトリガーがあるかどうかを調べることさえ考えていません。

一方、FOOデータベースに新しいものが作成されるたびに発生しなければならないロジックがある場合、それを配置する最も確実な場所は、FOOテーブルの挿入トリガーであるように思われます。

トリガーを使用するのは、の設定などの非常に単純な場合のみですModifiedDate

4

20 に答える 20

166

トリガーの主な問題は次のとおりです。

  • それらは完全にグローバルです-テーブルアクティビティのコンテキストに関係なく適用されます。
  • 彼らはステルスです。彼らが意図しない(そして非常に神秘的な)結果であなたを傷つけるまで、彼らがそこにいることを忘れがちです。

これは、適切な状況で慎重に使用する必要があることを意味します。私の経験では、これはリレーショナル整合性の問題に限定されています(宣言的に取得できるよりも細かい粒度の場合もあります)。通常、ビジネスやトランザクションの目的ではありません。YMMV。

于 2009-01-20T07:22:43.203 に答える
86

いいえ、実際には良い考えです。特定のトリガーに問題がある場合、それは正しく行われていませんが、それは通常、トリガー自体の概念ではなく、実装に問題があることを意味します:-)。

トリガーは、DBMS固有のアクティビティを、それが属するデータベースの制御下に置くため、頻繁に使用します。DBMSのユーザーは、そのようなことについて心配する必要はありません。データの整合性は、データベース自体にあり、データを使用するアプリケーションやユーザーにはありません。データベースに制約やトリガー、その他の機能がない場合、ルールを適用するのはアプリケーションに任されており、データを破棄するのに不正またはバグのあるアプリケーション/ユーザーが1人だけ必要です。

たとえば、トリガーがないと、自動生成された列などの不思議なものは存在せず、それらを選択するときに各行で関数を処理する必要があります。これにより、DBMSのパフォーマンスが低下する可能性があります。変更されるのはそれだけなので、挿入/更新時に自動生成された列を作成する方がはるかに優れています。

また、トリガーがないと、列が特定の形式になるように、プレトリガーなどのデータルールをDBMSに適用できなくなります。これは、通常は外部キーの検索であるデータ整合性ルールとは異なることに注意してください。

于 2009-01-20T07:16:04.857 に答える
55

ツールは決して悪ではありません。これらのツールの適用は悪である可能性があります。

于 2009-01-20T19:19:01.823 に答える
22

同意します。トリガーの問題は、トリガーではなく人です。見ること、考慮することが増え、コーダーが物事を正しくチェックする責任が増えますが、インデックスを破棄して生活を簡素化することはありません。(悪いインデックスは、悪いトリガーと同じくらい悪い可能性があります)

トリガーの重要性 (私の考えでは) は...
- どのシステムも常に有効な状態にある
必要があります - この有効な状態を強制するコードは一元化する必要があります (すべての SP に書かれているわけではありません)。

メンテナンスの観点から、トリガーは有能なコーダーにとって非常に便利であり、初心者/アマチュアにとっては問題です。それでも、これらの人々は何らかの方法で学び、成長する必要があります。

職場環境にもよると思います。よく学び、几帳面であると信頼できる信頼できる人がいますか? そうでない場合は、次の 2 つの選択肢が
あるようです。 - 補うために機能を失わなければならないことを受け入れる
- 別の人員またはより良いトレーニングと管理が必要であることを受け入れる

彼らは耳障りに聞こえます、そして私は彼らがそうであると思います。しかし、それは私の心の中での基本的な真実です...

于 2009-01-20T09:46:43.570 に答える
20

トリガーは悪であるだけでなく、優れたデータベース設計に必要だと思います。アプリケーション プログラマーは、データベースはアプリケーションによってのみ影響を受けると考えています。彼らはしばしば間違っています。データの変更がどこから行われたかに関係なくデータの整合性を維持する必要がある場合は、トリガーが必要であり、トリガーを避けるのは愚かなことです。有能なデータベース開発者であれば、トリガーの設計、テスト、またはトラブルシューティングを行うことは難しくありません。また、(私と同じように) あなたがそこに注目したとしても、トリガーが予期しない結果を引き起こしていると判断することは困難です。SP で参照していないテーブルに FK エラーがあるというエラーが表示された場合は、私は、トリガーが問題を引き起こしていることを考えずに知っています。有能なデータベース開発者なら誰でもそうすべきです。アプリケーションだけにビジネス ルールを配置することが、私が見つけた悪いデータの最大の原因です。他の人は、ルールが存在することすら知らず、プロセスで違反しているためです。データ中心のルールはデータベースに属し、トリガーはより複雑なルールを適用するための鍵となります。

于 2010-02-03T20:27:11.967 に答える
13

ほとんどの場合、はい。

トリガーの難しさは、「背後で」何かを行うことです。アプリケーションを保守している開発者は、アプリケーションがそこにあることを簡単に認識できず、気付かないうちに物事を台無しにする変更を加える可能性があります。

メンテナンス作業を追加するだけの複雑なレイヤーが作成されます。

トリガーを使用するのではなく、通常、ストアド プロシージャ/ルーチンで同じことを実行できますが、明確で保守しやすい方法で行うことができます。ストアド ルーチンを呼び出すと、開発者はそのソース コードを見て、何が起こっているかを正確に確認できます。

于 2009-01-20T10:15:16.617 に答える
9

トリガーは非常に強力で便利です。トリガーが問題の最善の解決策となるシナリオは数多くあります。

それらは非常に優れた「ハック」ツールでもあります。コードとデータベースの両方を直接制御できない状況がよくあります。コードの次のメジャー リリースまで 2 か月待たなければならないが、すぐにデータベースにパッチを適用できる場合は、テーブルにトリガーを配置して追加機能を実行できます。その後、コードのリリースが可能になったら、必要に応じて、このトリガーを同じ機能のコード化されたバージョンに置き換えることができます。

結局のところ、それが何をしているのかわからなければ、すべてが「悪」です。トリガーを理解していない開発者がいるからだと決めるのは、運転できない人がいるから車が悪だと主張するのと同じです...

于 2009-01-20T10:35:49.477 に答える
8

トリガーには用途があります。ログ/監査と「最終更新日」の維持は、以前の返信で言及されている 2 つの非常に優れた用途です。

ただし、優れた設計の核となる信条の 1 つは、ビジネス ルール/ビジネス ロジック/呼び名が何であれ、1 つの場所に集中する必要があるということです。一部のロジックを (トリガーまたはストアド プロシージャを介して) データベースに配置し、一部をアプリケーションに配置することは、その原則に違反します。両方の場所でロジックを複製すると、常に互いに同期が取れなくなるため、さらに悪いことになります。

すでに述べた「驚き最小の原則」の問題もあります。

于 2009-01-20T11:32:32.810 に答える
7

大まかに言うと、トリガーには 2 つの使用例があります1

1) 物事を「自動的に」実現すること。この場合、トリガーは副作用を引き起こします。実行された (プリミティブ) 演算子の挿入、更新、または削除が原因でトリガーが起動された場合、予想されなかった方法でデータが変更されます。

ここでの一般的なコンセンサスは、トリガーが実際に有害であるということです。INSERT、UPDATE、または DELETE ステートメントのよく知られたセマンティクスが変更されるためです。これら 3 つのプリミティブ SQL 演算子のセマンティクスを変更すると、将来、SQL プリミティブを使用して操作したときに期待どおりに動作しないデータベース テーブルで作業する必要がある他の開発者が苦しむことになります。

2) 宣言的に処理できるルール以外のデータ整合性ルールを強制するため (CHECK、PRIMARY KEY、UNIQUE KEY、および FOREIGN KEY を使用)。このユースケースでは、すべてのトリガーが実行するのは、INSERT/UPDATE/DELETE によって行われている変更が許可されているかどうかを確認するためのクエリ (SELECT) データです。宣言的制約が私たちに行うのと同じように。この場合のみ、私たち (開発者) は施行をプログラムしました。

後者のユースケースにトリガーを使用しても害はありません。

私はそれについてブログを書いています: http://harmfultriggers.blogspot.com

于 2011-11-30T13:59:25.453 に答える
6

トリガーは、適切に使用すると優れたツールです。特に、変更の監査、要約テーブルへの入力などに使用します。

これで、他のトリガーを開始する1つのトリガーで「トリガー地獄」に陥った場合、それらは「悪」になる可能性があります。私はかつて、彼らが「フレックストリガー」と呼んでいるものを備えたCOTS製品に取り組んだことがあります。これらのトリガーは、実行されるたびに動的SQL刺し傷がコンパイルされるため、テーブルに格納されました。コンパイルされたトリガーはルックアップを実行し、そのテーブルに実行するフレックストリガーがあるかどうかを確認してから、「フレックス」トリガーをコンパイルして実行します。理論的には、製品は簡単にカスタマイズできるため、これは本当にクールなアイデアのように聞こえましたが、実際には、すべてのコンパイルが必要だったため、データベースはかなり爆発しました...

そうですね、あなたがしていることを視野に入れておけば、彼らは素晴らしいです。監査、要約、自動シーケンスなどの非常に単純なものであれば、問題はありません。テーブルの成長率と、トリガーがパフォーマンスにどのように影響するかを覚えておいてください。

于 2009-03-03T15:55:51.757 に答える
5

悪ではない。彼らは実際に次のようなものを単純化します

1.レコードまたはデータベース スキーマへの変更のロギング/監査

本番環境での変更をロールバックする ALTER TABLE にトリガーを設定できます。これにより、偶発的なテーブルの変更を防ぐことができます。


2. 複数のデータベース間で参照整合性 (主キー/外部キーの関係など) を強化する

于 2009-01-20T10:28:15.140 に答える
5

トリガーは、必要な機能を実現するための最も直接的な方法である場合に常に使用する必要があると考えている開発者も、決して使用しない開発者も知っています。2 つの陣営の間のドグマのようなものです。

ただし、個人的には MarkR に完全に同意します。トリガーと機能的に同等のコードを (ほぼ) いつでも記述できます。これにより、より明確になり、保守が容易になります。

于 2009-01-20T10:22:51.297 に答える
4

彼らは間違いなく悪ではありません。データベース スキーマのリファクタリング中、列の名前を変更したり、列を 2 つの列に分割したり、その逆 (例: 名前/姓のケース) を行ったり、移行を支援したりするときに、トリガーが貴重であることがわかりました。

また、監査にも非常に役立ちます。

于 2010-04-29T06:51:26.360 に答える
4

それらが悪であると言うのは大袈裟ですが、メッシュの原因となる可能性があります。1 つのトリガーの発火が他のトリガーの発火を引き起こすと、非常に複雑になります。それらが面倒だとしましょう: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

トリガーを使用して Oracle でビジネス ロジックを実行することは、複数の同時実行の問題があるため、思ったよりも困難です。他のセッションがコミットされるまで、別のセッションの変更は表示されません。

于 2009-01-20T10:57:44.207 に答える
4

この回答は、特に SQL Server に適用されます。(ただし、他のRDBMSにも当てはまるかもしれませんが、私にはわかりません。ここで回答として提供することをお勧めしましたが、これはだまされて閉じられました。)

これまでの回答で言及されていない側面の 1 つは、セキュリティです。デフォルトでは、トリガーは、トリガーを起動させるステートメントを実行するユーザーのコンテキストで実行されるため、すべてのトリガーを確認しない限り、セキュリティ上の脅威が発生する可能性があります。

BOL の「トリガー セキュリティの管理GRANT CONTROL SERVER TO JohnDoe ;」の見出しの下に示されている例は、自分の権限をエスカレートするためにコードを含むトリガーを作成するユーザーのものです。

于 2011-04-24T12:36:17.327 に答える
3

私は彼らが悪である可能性があると思いますが、開発中の他のものと同じくらい悪です。

私は彼らとあまり経験がありませんが、私が取り組んだ最近のプロジェクトで彼らを持っていたので、この結論に至りました。私が彼らに抱えている問題は、ビジネスロジックがコードライブラリデータベースの2つの場所に配置される可能性があることです。

私はそれをsprocsを使用することと同様の議論として見ています。多くの場合、SQLがデータベースにビジネスロジックを書き込むのが本当に得意な開発者がいますが、そうでない人は他の場所にビジネスロジックを持っています。

だから私の経験則はあなたのプロジェクトの構造が何であるかを見ることです。データベースにビジネスロジックを格納することが実行可能であると思われる場合は、トリガーを設定すると便利です。

于 2009-01-20T10:40:21.090 に答える
3

いや、彼らは悪ではありません-彼らはただ誤解されています:-D

トリガーには有効な用途がありますが、最終的に事態を悪化させるレトロハックとしてはあまりにも頻繁に使用されます。

アプリケーションの一部としてDBを開発している場合、ロジックは常に呼び出しを行うコードまたはsprocに含まれている必要があります。トリガーは、後でデバッグの痛みにつながるだけです。

ロック、デッドロック、およびDBがディスク上のファイルにアクセスする方法を理解している場合は、トリガーを正しい方法で使用すること(たとえば、直接DBアクセスの監査またはアーカイブ)は非常に価値があります。

于 2009-01-20T10:44:24.653 に答える
3

副作用がある場合、それは設計上の問題です。一部のデータベースシステムでは、自動インクリメントフィールドを設定する他の可能性はありません。つまり、主キーIDフィールド用です。

于 2009-01-20T07:03:51.323 に答える
1

実際、トリガーが悪用されることがよくあります。実際、ほとんどの場合、それらは必要ありません。しかし、それは必ずしも彼らを悪くするわけではありません。

トリガーが役立つシナリオは、ソースコードがなく、変更する方法がないレガシーアプリケーションがある場合です。

于 2009-01-20T07:23:41.640 に答える
1

トリガーのアイデアは悪ではありません。トリガーのネストを制限することは悪です。

于 2010-02-16T18:59:36.907 に答える