web-dev-qa-db-ja.com

データベースのトリガーは悪ですか?

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

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

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

トリガーを使用しているのは、ModifiedDateの設定などの本当に簡単なことだけです。

177
WW.

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

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

141
dkretz

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

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

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

また、トリガーの欠如は、列が特定の形式を持っていることを確認するために、事前トリガーなどのDBMSでデータルールが適用されないようにします。これは、一般的に単なる外部キー検索であるデータ整合性ルールとは異なることに注意してください。

74
paxdiablo

ツールは決して悪ではありません。これらのツールのアプリケーションは悪である可能性があります。

45
Andy Webb

トリガーは監査ログに適しているようです。

20
derobert

同意する。トリガーの問題は、トリガーではなく人です。見ること、考慮すること、そして物事を正しくチェックするコーダーの負担を増やすことの方が多くありますが、私たちは生活をより簡単にするためにインデックスを破棄しません。 (悪いインデックスは悪いトリガーと同じくらい悪い可能性があります)

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

メンテナンスの観点から見ると、トリガーは競合するコーダーや、ジュニア/アマチュアのコーダーにとって非常に便利です。しかし、これらの人々は何とかして学び、成長する必要があります。

私はそれがあなたの作業環境に帰着すると思います。よく学習し、整然として信頼できる信頼できる人がいますか?そうでない場合は、2つの選択肢があるようです。
-補償するために機能を失う必要があることを受け入れます
-別の人またはより良いトレーニングと管理が必要であることを受け入れる

耳障りな音がするが、そうだと思う。しかし、それは私の心の中の基本的な真実です...

20
MatBailie

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

18
HLGEM

ほとんど、はい。

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

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

トリガーを使用するのではなく、ストアドプロシージャ/ルーチンは通常同じことを行うことができますが、明確で保守可能な方法で実行できます。

13
MarkR

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

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

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

9
Robin Day

トリガーには用途があります-ロギング/監査および「最終変更」日付の維持は、以前の返信で言及された2つの非常に優れた用途です。

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

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

7
Dave Sherohman

高レベルでは、トリガーの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

6
Toon Koppelaars

トリガーは、適切に使用すると良いツールです。特に、変更の監査、要約テーブルへの入力などの場合.

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

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

6
tmeisenh

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

しかし、個人的にはMarkRに完全に同意しています。トリガーと同等の機能的に同等のコードを(ほぼ)いつでも書くことができます。

5
DanSingerman

悪ではありません。彼らは実際に

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

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


2.複数のデータベース間で参照整合性(プライマリ/外部キー関係など)を強制する

5
Chris

この回答は、特にSQL Serverに適用されます。 (他のRDBMSにも当てはまるかもしれませんが、私は考えていません。答えとして here を指定した方がよいと思いますが、これはだまされて閉じられました。)

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

Managing Trigger Security 」という見出しの下にあるBOLの例は、独自のパーミッションをエスカレートするためにコードGRANT CONTROL SERVER TO JohnDoe ;を含むトリガーを作成するユーザーのものです。

4
Martin Smith

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

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

4
Stefano Borini

いや、彼らは悪ではない-彼らはただ誤解されている:-D

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

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

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

4
Keith

彼らが悪であると言うのは大げさですが、彼らはメッシュの原因になる可能性があります。 1つのトリガーの起動により他のトリガーが起動されると、本当に複雑になります。面倒だとしましょう: http://www.Oracle.com/technology/oramag/Oracle/08-sep/o58asktom.html

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

3
tuinstoel

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

3
Xn0vv3r

私は彼らが悪であると思うが、開発中の他のものと同じくらい悪であるだけだ。

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

私はそれをsprocsを使用した同様の議論と見ています。多くの場合、SQLに非常に優れた開発者がデータベースにビジネスロジックを書き込むことができますが、そうでない開発者には他の場所にビジネスロジックがあります。

したがって、私の経験則では、プロジェクトの構造を確認します。データベースにビジネスロジックを保存することが実行可能と思われる場合は、トリガーを使用すると便利です。

3
Aaron Powell

実際、トリガーが悪用されることは非常に多くあります。実際、ほとんどの場合、それらは必要ありません。しかし、それは必ずしも悪いことではありません。

トリガーが便利なのは、ソースコードがないレガシーアプリケーションがあり、それを変更する方法がない場合です。

1
ibz

トリガーのアイデアは悪ではなく、トリガーのネストを制限することは悪です。

1
alpav