MySQL에서 트리거(Trigger) 사용법

트리거(Trigger)는 MySQL에서 데이터베이스에 특정 변경이 발생할 때 자동으로 실행되는 SQL 명령어입니다.

데이터가 INSERT, UPDATE, DELETE 될 때 자동으로 동작하여, 데이터의 무결성 유지를 돕거나 복잡한 작업을 자동화할 수 있습니다. 

 

 

1. 트리거(Trigger)란?

트리거(Trigger)는 특정 테이블에 대해 데이터 변경 작업이 이루어질 때 자동으로 실행되는 저장 프로시저입니다. 트리거는 주로 데이터 무결성 검사, 로그 기록, 테이블 간의 관계를 관리하는 데 사용됩니다. 트리거는 데이터베이스의 특정 이벤트(INSERT, UPDATE, DELETE)에 반응하여 실행됩니다.

트리거의 주요 특징

  • 데이터 변경이 발생할 때 자동으로 실행됩니다.
  • 트리거는 특정 테이블에 대해 설정됩니다.
  • INSERT, UPDATE, DELETE 작업에 반응할 수 있습니다.
  • 트리거는 한 번만 실행되며, 특정 시점(전후)에 실행될 수 있습니다.

 

2. 트리거 생성하기

트리거를 생성하려면 CREATE TRIGGER 명령어를 사용합니다. 트리거는 언제 실행될지에 대한 시점과 어떤 작업에 반응할지에 대한 정의가 필요합니다. MySQL에서 트리거는 다음 네 가지 시점에 실행할 수 있습니다:

  • BEFORE: 데이터 변경 전에 트리거가 실행됩니다.
  • AFTER: 데이터 변경 후 트리거가 실행됩니다.

트리거 생성 예시

CREATE TRIGGER update_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
SET NEW.updated_at = NOW();

위 예시는 users 테이블에서 데이터가 수정되기 전에 updated_at 컬럼을 현재 시간으로 업데이트하는 트리거입니다. 이 트리거는 BEFORE UPDATE 시점에 실행되며, 데이터가 변경되기 전에 새로운 타임스탬프 값을 설정합니다.

 

 

3. 트리거 활용 예시

트리거는 데이터베이스의 자동화 작업을 구현할 때 유용하게 사용됩니다. 다음은 여러 가지 실용적인 트리거 활용 예시입니다.

예시 1: 주문 테이블에 데이터 삽입 시 재고 수량 자동 감소

주문이 들어오면 자동으로 재고 수량을 줄여주는 트리거를 만들 수 있습니다.

CREATE TRIGGER update_stock
AFTER INSERT ON orders
FOR EACH ROW
UPDATE products
SET stock = stock - NEW.quantity
WHERE product_id = NEW.product_id;

위 트리거는 orders 테이블에 새로운 주문이 삽입될 때마다 해당 주문의 제품의 재고를 자동으로 감소시킵니다. AFTER INSERT 시점에 실행되며, 새로 삽입된 주문의 제품 수량을 사용하여 재고를 업데이트합니다.

예시 2: 삭제된 데이터 기록하기

데이터가 삭제될 때마다 삭제된 데이터를 기록하는 로그 테이블을 자동으로 업데이트하는 트리거를 만들 수 있습니다.

CREATE TRIGGER log_deleted_users
AFTER DELETE ON users
FOR EACH ROW
INSERT INTO deleted_users_log (user_id, username, deleted_at)
VALUES (OLD.user_id, OLD.username, NOW());

위 트리거는 users 테이블에서 데이터가 삭제될 때마다 해당 사용자의 ID와 이름을 deleted_users_log 테이블에 기록합니다. AFTER DELETE 시점에 실행되며, 삭제된 데이터의 정보를 기록합니다.

예시 3: 가격 변경 시 이력 기록

상품의 가격이 변경될 때마다 가격 변경 이력을 기록하는 트리거를 만들 수 있습니다.

CREATE TRIGGER track_price_change
AFTER UPDATE ON products
FOR EACH ROW
IF OLD.price != NEW.price THEN
    INSERT INTO price_history (product_id, old_price, new_price, change_date)
    VALUES (NEW.product_id, OLD.price, NEW.price, NOW());
END IF;

위 트리거는 products 테이블에서 가격이 변경될 때마다 변경 전과 후의 가격을 price_history 테이블에 기록합니다. 가격이 변경된 경우에만 실행되도록 IF 조건을 추가했습니다.

 

 

4. 트리거의 제약 사항

트리거는 매우 유용하지만, 몇 가지 제약 사항이 있습니다. 이를 이해하고 적절히 사용하는 것이 중요합니다.

  • 트리거는 순차적으로 실행됩니다. 트리거 내에서 또 다른 트리거를 호출하면 순차적으로 실행되며, 성능에 영향을 미칠 수 있습니다.
  • 트리거는 다른 트리거를 호출할 수 없습니다. 트리거는 다른 트리거를 직접 호출할 수 없으며, 복잡한 작업을 처리하는 데 제한이 있을 수 있습니다.
  • 디버깅이 어려울 수 있습니다. 트리거가 자동으로 실행되기 때문에 발생한 오류를 추적하고 디버깅하는 데 어려움이 있을 수 있습니다.
  • 트리거는 트랜잭션 내에서 실행됩니다. 트리거 내에서 발생한 오류는 전체 트랜잭션을 롤백시키며, 트리거에서 오류가 발생하면 변경 작업도 취소됩니다.

트리거를 잘 활용하면 데이터베이스에서 자동화된 작업을 효율적으로 처리할 수 있으며, 데이터 무결성을 유지하는 데 매우 유용합니다.