3

トリガーの作成ページで MySql 5.0 のコメント ストリームを読んでいましたが 、推奨事項が適切かどうか、およびそれらが 5.1 にも適用されるかどうかをコミュニティに尋ねたいと思います。今日トリガーをいじって気付いたのは、AFTER UPDATE を使用して古いテーブルのフィールドを更新することは不可能だということです。

  1. BEFORE トリガーには注意してください。特に InnoDB エンジンを使用している場合、挿入は失敗しますが、BEFORE トリガーからのアクションは成功するという制約が発生する可能性があります。
  2. BEFORE トリガーは、トランザクションではなく、主に制約またはルールに使用し、NEW.* 列を微調整することは問題ありません。
  3. 履歴テーブルへの挿入や非正規化の更新など、他のほとんどの操作では AFTER トリガーを使用してください。
4

1 に答える 1

13

Yes. AFAIK, MySQL 5.1 did not make any changes to the semantics of how triggers work. MySQL tries to support the ANSI/ISO SQL specification for trigger semantics.

You can imagine there's a sequence of operations that runs as a row is written to the database:

  1. Run BEFORE triggers
  2. Evaluate constraints, enforce NOT NULL, apply DEFAULT values
  3. Write the row to the database
  4. Update indexes
  5. Run AFTER triggers

Once you've reached the AFTER trigger, it's too late to change values in the row. In some databases, you can set NEW.somecolumn = 1234 but this change is silently discarded as the AFTER trigger finishes. In other databases, it helps you understand your mistake by giving you an error either when you define the trigger or when you run the trigger.

AFTER triggers are best used for extra actions to take as a result of INSERT/UPDATE of the row, such as the audit logging you mentioned. For one thing, MySQL only permits one trigger per action per table, so if you are also using a BEFORE trigger to change values and enforce business rules, now you can at least keep the extra actions in a separate trigger. That makes it easier to update one or the other.

The other consideration is that you should probably do extra actions only after you know the row has been saved successfully. E.g. it wouldn't be right to log a change in a BEFORE trigger, and then have the change abort because of a NOT NULL constraint.

For DELETE actions where you need to remove dependent rows in other tables, you may still have to do that in a BEFORE trigger.

于 2009-01-02T21:16:02.160 に答える