Programmingデータベースエンジニア / DBA

SQLにおけるトリガーの動作原理、その利点と欠点、典型的な使用シナリオを説明してください。実際のトリガーの例を示してください。

Hintsage AIアシスタントで面接を突破

回答

トリガーは、特定のコード(通常はSQLやPostgreSQL用のPL/pgSQLなどの手続き言語)を指定されたイベント(INSERT、UPDATE、DELETE)が発生したときに自動的に実行するデータベースの特別なオブジェクトです。

利点:

  • ビジネスロジックとデータのバリデーションを集中管理。
  • 自動化された監査(例:変更履歴)。

欠点:

  • 隠れた実行 — トリガーが実行されたことが必ずしも明確ではない。
  • テーブルの頻繁な変更によるパフォーマンスの低下。
  • デバッグやトラブルシューティングの難しさ、無限ループのリスク(再帰トリガー)。
  • データマイグレーションが難しくなる。

使用するタイミング:

  • データの監査。
  • 関連するレコードの自動作成。
  • 標準手段では不可能な制約の制御を実現。

トリガーの例(PostgreSQL):

CREATE TABLE employee_audit ( id SERIAL PRIMARY KEY, employee_id INT, old_salary NUMERIC, new_salary NUMERIC, changed_at TIMESTAMP ); CREATE OR REPLACE FUNCTION audit_salary() RETURNS TRIGGER AS $$ BEGIN IF NEW.salary <> OLD.salary THEN INSERT INTO employee_audit(employee_id, old_salary, new_salary, changed_at) VALUES (OLD.id, OLD.salary, NEW.salary, NOW()); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_salary_update AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION audit_salary();

探索的な質問

トリガーの内部で、設定された同じテーブルを更新することはできますか?何が起こりますか?

回答:
トリガーがテーブルのUPDATEイベントに設定されているとき、その内部で同じテーブルに対してさらにUPDATEを実行すると、無限再帰(ループ)が発生し、コマンドが異常終了したり、トリガーの深さを超えるエラーが発生します。したがって、再帰が発生しないように常に監視するか、再帰的な呼び出しを許可または禁止するオプションを使用してください。

例:

-- この構造により、トリガーをループさせることができる: CREATE OR REPLACE FUNCTION recursive_update() RETURNS TRIGGER AS $$ BEGIN UPDATE employees SET salary = salary * 1.01 WHERE id = NEW.id; -- 再び実行される RETURN NEW; END; $$ LANGUAGE plpgsql;

ストーリー

会計CRMには、取引テーブルの変更時に操作をログに自動記録するトリガーが導入されました。高負荷下でサービスの動作が遅くなり、分析の結果、トリガーがログへの挿入に非常に多くの時間を消費し、最適化されていなかったことが判明しました(たとえば、重要なイベントのみを記録していました)。


ストーリー

在庫管理プロジェクトでは、ポジションのIDを計算するためにBEFORE INSERTトリガーが使用されていました。IDの不適切なロジックはデータの重複を引き起こし、そのエラーは「舞台裏」で動作していたため、長い間気づかれませんでした。


ストーリー

HRプラットフォームでは、各INSERT時に親テーブルと子テーブルのレコードを一括更新するトリガーが動作していました。トリガーのロジックのエラーにより再帰が発生し、テーブルに対するすべての操作が完全にブロックされました。トリガーを無効にし、テーブルを解除するために複雑なロールバック操作を行わなければなりませんでした。