🗄️ 데이터베이스

트리거

Trigger

이벤트 발생 시 자동 실행되는 프로시저.

상세 설명

트리거(Trigger)는 특정 이벤트(INSERT, UPDATE, DELETE)가 발생할 때 자동으로 실행되는 데이터베이스 프로시저입니다. 테이블에 대한 변경이 발생하면 사전(BEFORE) 또는 사후(AFTER)에 정의된 동작을 수행합니다.

트리거는 데이터 무결성 유지(복잡한 비즈니스 규칙 적용), 감사 로그 자동 기록, 파생 데이터 자동 계산, 연관 테이블 동기화 등에 활용됩니다. 또한 INSTEAD OF 트리거를 사용해 뷰에 대한 수정 작업을 처리할 수도 있습니다.

다만 트리거는 암묵적으로 실행되어 디버깅이 어렵고, 트리거가 다른 트리거를 호출하는 연쇄 실행이 발생할 수 있습니다. 성능에도 영향을 주므로 과도한 사용은 피해야 하며, 비즈니스 로직은 가능하면 애플리케이션 레벨에서 처리하는 것이 권장됩니다.

코드 예제

-- MySQL 트리거: 감사 로그 자동 기록
DELIMITER //
CREATE TRIGGER log_user_update
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
    INSERT INTO user_audit_log (
        user_id,
        old_email,
        new_email,
        changed_at,
        changed_by
    ) VALUES (
        OLD.id,
        OLD.email,
        NEW.email,
        NOW(),
        CURRENT_USER()
    );
END //
DELIMITER ;

-- PostgreSQL 트리거: 자동 타임스탬프 갱신
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER set_updated_at
BEFORE UPDATE ON orders
FOR EACH ROW
EXECUTE FUNCTION update_modified_column();

-- BEFORE 트리거: 데이터 검증 및 수정
DELIMITER //
CREATE TRIGGER validate_price
BEFORE INSERT ON products
FOR EACH ROW
BEGIN
    IF NEW.price < 0 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Price cannot be negative';
    END IF;

    -- 자동으로 할인가 계산
    IF NEW.discount_rate IS NOT NULL THEN
        SET NEW.discounted_price = NEW.price * (1 - NEW.discount_rate);
    END IF;
END //
DELIMITER ;

-- 재고 자동 감소 트리거
CREATE OR REPLACE FUNCTION decrease_stock()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE products
    SET stock = stock - NEW.quantity
    WHERE id = NEW.product_id;

    IF NOT FOUND THEN
        RAISE EXCEPTION 'Product not found: %', NEW.product_id;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER on_order_item_insert
AFTER INSERT ON order_items
FOR EACH ROW
EXECUTE FUNCTION decrease_stock();

실무 대화 예시

보안 담당자: 중요 테이블 변경 이력을 모두 남겨야 하는데, 애플리케이션 코드 수정이 많이 필요할까요?

DBA: 트리거로 하면 애플리케이션 코드 수정 없이 가능해요. UPDATE, DELETE 트리거에서 감사 테이블에 기록하면 됩니다.

백엔드 개발자: 트리거 쓰면 성능에 영향 있지 않나요?

DBA: 약간 있지만, 감사 로그 정도는 괜찮아요. 단, 복잡한 로직은 피하고 INSERT만 하는 게 좋습니다.

면접관: 트리거 사용 시 주의점은 뭐가 있나요?

지원자: 첫째, 트리거는 암묵적으로 실행되어 디버깅이 어렵습니다. 둘째, 트리거가 트리거를 호출하는 연쇄 실행이 발생할 수 있어 무한 루프나 성능 저하가 생길 수 있습니다. 셋째, 매 행마다 실행되므로 대량 데이터 처리 시 성능 이슈가 있습니다.

면접관: 그럼 언제 트리거를 쓰는 게 적절할까요?

지원자: 감사 로그, 자동 타임스탬프 갱신 같이 단순하고 필수적인 작업에 적합합니다. 복잡한 비즈니스 로직은 애플리케이션에서 처리하는 게 좋습니다.

시니어: 이 트리거에서 외부 API를 호출하네요. 문제 없어요?

주니어: 주문 생성할 때 알림을 보내려고요.

시니어: 트리거는 트랜잭션 내에서 동기적으로 실행돼요. API 타임아웃나면 INSERT도 실패합니다. 이런 건 메시지 큐나 애플리케이션에서 비동기로 처리해야 해요.

주의사항

관련 용어

더 배우기