데이터베이스 트리거(Trigger)는 특정 테이블에 INSERT, UPDATE, DELETE 이벤트가 발생할 때 자동으로 실행되는 특수 프로시저다. 감사 로그, 데이터 무결성 유지, 자동 계산 등에 활용된다.
트리거 구조
sql
-- 트리거 = 이벤트 + 조건 + 동작
CREATE TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} -- 실행 시점
{INSERT | UPDATE | DELETE} -- 이벤트
ON table_name
FOR EACH {ROW | STATEMENT} -- 행 단위 or 문 단위
[WHEN (condition)] -- 조건
EXECUTE FUNCTION trigger_function();
실전 예시: 감사 로그
sql
-- 감사 로그 테이블
CREATE TABLE audit_log (
id SERIAL PRIMARY KEY,
table_name TEXT,
operation TEXT,
old_data JSONB,
new_data JSONB,
changed_by TEXT DEFAULT current_user,
changed_at TIMESTAMP DEFAULT NOW()
);
-- 트리거 함수
CREATE OR REPLACE FUNCTION log_changes()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation, old_data, new_data)
VALUES (
TG_TABLE_NAME,
TG_OP,
CASE WHEN TG_OP = 'DELETE' THEN row_to_json(OLD) ELSE NULL END,
CASE WHEN TG_OP IN ('INSERT','UPDATE') THEN row_to_json(NEW) ELSE NULL END
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 트리거 등록
CREATE TRIGGER audit_users
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION log_changes();
트리거 실행 시점 비교
| 시점 | 설명 | 용도 |
|---|
| BEFORE | 실제 변경 전 실행 | 데이터 검증, 값 수정 |
| AFTER | 실제 변경 후 실행 | 감사 로그, 후속 처리 |
| INSTEAD OF | 뷰에만 사용, 동작 대체 | 업데이트 불가 뷰 처리 |
NEW / OLD 참조
sql
-- INSERT: NEW만 존재
-- UPDATE: OLD(이전) + NEW(이후)
-- DELETE: OLD만 존재
CREATE OR REPLACE FUNCTION update_modified_time()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW(); -- 수정 시간 자동 업데이트
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON products
FOR EACH ROW EXECUTE FUNCTION update_modified_time();
트리거 주의사항
- •성능: 모든 DML에 트리거가 실행되므로 과도한 트리거는 성능 저하
- •순환 트리거: 트리거 내에서 같은 테이블 수정 시 무한 루프 주의
- •디버깅 어려움: 암묵적 실행으로 원인 파악 어려울 수 있음
관련 개념