Database

Trigger

kyoulho 2024. 8. 16. 16:13
  • 데이터베이스에서 특정 이벤트가 발생할 때 자동으로 실행되는 특별한 유형의 프로시저이다.
  • 특정 테이블에서 데이터가 변경될 때(INSERT, UPDATE, DELETE) 자동으로 실행되며, 보통 데이터 무결성을 유지하거나 자동으로 로그를 기록하는 데 사용된다.
  • 자동화: 데이터 변경 시 자동으로 실행되므로, 데이터 무결성을 유지하거나 특정 작업을 자동화할 수 있다.
  • 일관성: 동일한 작업을 반복적으로 수행할 수 있어 데이터베이스 내에서 일관성을 유지할 수 있다.
  • 보안: 트리거를 사용해 민감한 데이터 변경을 감지하고 로그를 기록하거나 특정 행동을 취할 수 있다.
  • 가시성 부족: 트리거는 자동으로 실행되므로, 디버깅이 어렵고 예상치 못한 동작을 유발할 수 있다.
  • 성능 저하: 잘못 설계된 트리거는 성능 저하를 초래할 수 있다. 특히 트리거가 연쇄적으로 실행될 경우 문제가 발생할 수 있다.
  • 복잡성: 트리거는 복잡한 로직을 포함할 수 있어 유지보수가 어려워질 수 있다.

 

예시 1

이 트리거는 사용자가 닉네임을 변경할 때마다 이전 닉네임을 로그에 기록한다.

delimiter $$
CREATE TRIGGER log_user_nickname_trigger
BEFORE UPDATE
ON users FOR EACH ROW -- users 테이블의 각 row에서 update가 발생하면 트리거된다.
BEGIN
    INSERT INTO users_log VALUES (OLD.id, OLD.nickname, NOW());
END $$
delimiter ;
  • OLD: UPDATE 또는 DELETE 작업이 발생하기 전의 튜플을 참조한다.

 

예시 2

이 트리거는 사용자가 상품을 구매할 때마다 누적된 구매 금액을 업데이트한다.

delimiter $$
CREATE TRIGGER sum_buy_prices_trigger
AFTER INSERT
ON buy FOR EACH ROW
BEGIN
    DECLARE total INT;
    DECLARE user_id INT DEFAULT NEW.user_id; -- buy 테이블에서 insert된 튜플의 user_id

    SELECT SUM(price) INTO total FROM buy WHERE user_id = user_id;
    UPDATE user_buy_stats SET price_sum = total WHERE user_id = user_id;
END $$
delimiter ;
  • NEW: INSERT된 튜플 또는 UPDATE된 후의 튜플을 참조한다.

 

FOR EACH STATEMENT

MySQL에서 지원하지 않지만, 일부 데이터베이스에서는 FOR EACH STATEMENT 트리거를 사용해 하나의 트랜잭션에서 발생한 모든 행 변경을 처리할 수 있다.

CREATE TRIGGER avg_empl_salary_trigger
AFTER INSERT OR UPDATE OR DELETE
ON employee 
FOR EACH STATEMENT
EXECUTE FUNCTION update_avg_empl_salary();

 

조건부 트리거

특정 조건을 만족할 때만 트리거가 실행되도록 설정할 수 있다. MySQL에서는 지원하지 않지만, 다른 DBMS에서는 가능하다.

CREATE TRIGGER log_user_nickname_trigger
BEFORE UPDATE
ON users
FOR EACH ROW
WHEN(NEW.nickname IS DISTINCT FROM OLD.nickname)
EXECUTE FUNCTION log_user_nickname();

'Database' 카테고리의 다른 글

Recoverability  (0) 2024.08.16
Serializability  (0) 2024.08.16
Stored Procedure  (0) 2024.08.16
Stored Function  (0) 2024.08.15
데이터베이스 기본 개념  (0) 2024.08.15