변수의 기록

(데이터베이스)트리거(Trigger)란? — Oracle 기준으로 정리하는 SQL 트리거의 개념과 실무 주의사항 본문

CS지식/데이터베이스 (Database)

(데이터베이스)트리거(Trigger)란? — Oracle 기준으로 정리하는 SQL 트리거의 개념과 실무 주의사항

불광동 물주먹 2025. 5. 17. 23:25

트리거(Trigger)란? — Oracle 기준으로 정리하는 SQL 트리거의 개념과 실무 주의사항

1. 트리거(Trigger)의 사전적 의미와 개념

Trigger는 사전적으로는 아래와 같은 의미를 가집니다:

  1. 총기의 방아쇠
  2. 사건을 유발하는 계기
  3. 어떤 반응을 촉발시키는 요소 (to set off)
  4. 자동 작동시키는 장치 (to set on)

이를 데이터베이스 관점에서 해석하면 다음과 같습니다:

트리거는 특정 이벤트(INSERT, UPDATE, DELETE)가 발생했을 때 자동으로 실행되는 절차형 객체로, 명시적으로 호출하지 않아도 자동으로 작동하는 DB 내부 로직입니다.

Oracle DB에서 트리거는 테이블 또는 뷰에 부착되며, 다음과 같은 구조로 동작합니다:

  • BEFORE 또는 AFTER 특정 DML(INSERT, UPDATE, DELETE) 발생 시점 지정
  • FOR EACH ROW 또는 FOR EACH STATEMENT 단위 지정 가능
  • 조건부 실행 가능 (WHEN 조건 사용)

2. 트리거 기본 예제 (Oracle 기준)

다음은 Oracle에서 직원 테이블에 새로운 직원이 추가될 때, 로그 테이블에 기록을 남기는 트리거 예제입니다.

-- 로그 테이블 생성
CREATE TABLE emp_log (
    log_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
    emp_name VARCHAR2(100),
    action VARCHAR2(10),
    log_time TIMESTAMP DEFAULT SYSTIMESTAMP
);

-- 트리거 생성
CREATE OR REPLACE TRIGGER trg_emp_insert
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
    INSERT INTO emp_log (emp_name, action)
    VALUES (:NEW.name, 'INSERT');
END;
/
 

설명:

  • AFTER INSERT: insert가 완료된 직후 동작
  • FOR EACH ROW: 삽입된 각 행에 대해 실행
  • :NEW.name: 새로 삽입되는 값에 접근 (OLD는 삭제/수정 시 사용)

3. 트리거의 세부 설정 요소 (Oracle 기준)

1) DML 이벤트 지정

CREATE OR REPLACE TRIGGER trg_test
BEFORE INSERT OR UPDATE OR DELETE ON some_table
 

2) 행 단위 vs 문 단위

  • FOR EACH ROW: 각 행마다 트리거 실행 (기본)
  • FOR EACH STATEMENT: 전체 DML 문장에 대해 1번만 실행
 
-- 문(statement) 단위 트리거
CREATE OR REPLACE TRIGGER trg_stmt
AFTER INSERT ON orders
BEGIN
  -- 전체 insert 문에 대해 한 번만 실행
  INSERT INTO log_table (message) VALUES ('INSERT on orders');
END;
/

 

※ MySQL은 FOR EACH STATEMENT를 지원하지 않음


3) 조건부 트리거 실행 (WHEN 절)

 
CREATE OR REPLACE TRIGGER trg_update_salary
BEFORE UPDATE ON employees
FOR EACH ROW
WHEN (NEW.salary > 10000)
BEGIN
    DBMS_OUTPUT.PUT_LINE('High salary update detected');
END;
/
 

Oracle에서는 WHEN 절을 통해 특정 조건에서만 트리거 실행이 가능합니다. MySQL은 이 기능 미지원.


4. 트리거 사용 시 주의사항

1) 비가시적 로직으로 인한 디버깅 어려움

  • 애플리케이션 코드나 쿼리에서 트리거는 명시적으로 드러나지 않음
  • 어떤 데이터 조작에 의해 트리거가 실행되는지 외부에서 확인하기 어려움
  • 로직이 숨어 있어서 문제 발생 시 원인 추적 어려움

2) 트리거 간의 의존성 꼬임

  • 트리거 내부에서 또 다른 트리거를 유발할 수 있음 (Cascade Trigger)
  • 순환 호출로 이어질 경우, 무한 루프나 성능 저하 발생 가능
  • 예외 처리가 어려운 구조가 되므로 실무에서는 트리거 간 의존성을 피해야 함

3) 성능 저하

  • 트리거는 자동 실행되기 때문에, 의도하지 않게 많은 부하를 유발할 수 있음
  • 특히 대량 insert/update/delete 작업 시, 매번 트리거 로직이 실행되어 DB 응답 지연 발생 가능

4) 문서화의 중요성

  • 트리거 로직은 소스 코드가 아닌 DB 내부에 존재함
  • 정상적인 협업 및 유지보수 위해 반드시 문서화 필요
    • 어떤 테이블에 어떤 트리거가 존재하는지
    • 트리거의 이벤트, 조건, 실행 시점 등

5. 트리거는 언제 쓰는 것이 좋은가?

실무에서는 트리거를 다음과 같은 경우에 제한적으로 사용하는 것이 권장됩니다.


상황 트리거 사용 권장 여부
입력 로그 기록 사용 가능 (ex. 감사 로그 테이블)
테이블 간 데이터 동기화 지양 (Application 레벨 추천)
복잡한 비즈니스 로직 처리 비추천
데이터 무결성 검사 제약조건(Constraint)이나 Application에서 처리 권장
 

6. 결론 — 트리거는 최후의 수단으로

트리거는 강력하지만 가시성, 유지보수, 성능 측면에서 단점이 명확한 도구입니다. 따라서 다음과 같은 자세가 필요합니다:

  • 트리거가 정말 필요한 상황인지 먼저 검토
  • 가능한 경우 애플리케이션 레이어 또는 명시적 프로시저 호출로 대체
  • 사용한다면 단순하고 독립적인 트리거만 허용, 반드시 문서화할 것

트리거는 데이터 보호나 감사(audit) 목적처럼 "명시적으로 건드리기 어려운 영역"을 보완할 때에만 사용하는 것이 바람직합니다.