監査ログを維持するためのBEFOREまたはAFTERトリガー
質問
トリガーページの作成 推奨事項が良いかどうか、コミュニティに尋ねたいと思います。まだ5.1に適用されるかどうか。今日トリガーで遊んでいることに気付いたのは、AFTER UPDATEを使用して古いテーブルのフィールドを更新することは不可能だということです。
- BEFOREトリガーには注意してください。特にInnoDBエンジンを使用している場合、挿入は失敗しますが、BEFOREトリガーからのアクションは成功します。制約が発生する可能性があります。
- トランザクションではなく、主に制約またはルールにBEFOREトリガーを使用し、NEW。*列を微調整する必要があります。
- 履歴テーブルへの挿入や非正規化の更新など、他のほとんどの操作でAFTERトリガーを使用するスティック。
解決
はい。知る限り、MySQL 5.1はトリガーの動作のセマンティクスに変更を加えていません。 MySQLは、トリガーセマンティクスのANSI / ISO SQL仕様をサポートしようとします。
行がデータベースに書き込まれるときに実行される一連の操作があると想像できます。
- トリガーの前に実行
- 制約の評価、
NOT NULL
の実施、DEFAULT
値の適用 - 行をデータベースに書き込む
- インデックスの更新
- AFTERトリガーの実行
AFTERトリガーに到達すると、行の値を変更するには遅すぎます。一部のデータベースでは、 NEW.somecolumn = 1234
を設定できますが、この変更はAFTERトリガーが終了すると静かに破棄されます。他のデータベースでは、トリガーを定義するとき、またはトリガーを実行するときにエラーが表示されるため、間違いを理解するのに役立ちます。
AFTERトリガーは、前述の監査ログなど、行のINSERT / UPDATEの結果として実行する追加のアクションに最適です。 1つには、MySQLはテーブルごとのアクションごとに1つのトリガーのみを許可するため、BEFOREトリガーも使用して値を変更し、ビジネスルールを適用する場合、少なくとも追加のアクションを別のトリガーに保持できます。これにより、どちらか一方を簡単に更新できます。
他の考慮事項は、行が正常に保存されたことがわかった後にのみ 追加のアクションを実行することです。例えば。 BEFOREトリガーで変更をログに記録し、NOT NULL制約のために変更を中止するのは正しくありません。
他のテーブルの依存行を削除する必要があるDELETEアクションの場合、BEFOREトリガーでそれを行う必要がある場合があります。