설명
간단한 예시 : 계정정지, 복구 프로세스
어떤 클라이언트가 서비스 탈퇴를 신청하였다. 내부에서는 회원테이블에서 해당하는 계정을 삭제한다. 만약 일정 기간 이후 클라이언트가 서비스를 사용해야할 일이 생겨 계정을 다시 사용코자 가입을 하려는데 이미 가입된 이력이 있는 회원정보인 것이다. 이때 새로 생성이 아닌 계정복구를 한다.
서비스에서는 단순히 회원 데이터를 저장하면 안된다. 복구도 가능하게 설계해야한다.
예를 들어 어떤 사용자가 서비스 탈퇴를 요청했다면, 회원 테이블에서 해당 사용자의 정보를 삭제하는 SQL을 실행하게 됩니다.
하지만 현실적으로는 이 사용자의 정보를 완전히 삭제해버리면 안된다. 왜냐하면
이처럼 데이터 변경 이벤트가 발생할 때, 자동으로 필요한 작업을 수행해주는 것이 바로 트리거(Trigger)
1. 사용자가 탈퇴 요청
member 테이블에서 해당 사용자의 정보를 DELETE2. 트리거가 자동으로 작동
DELETE 문이 실행되는 순간, DB에 설정된 트리거가 자동 발동member_deleted 테이블에 자동으로 저장AFTER DELETE ON member
3. 결과
4. 사용자가 재가입하려 할 때
FOR EACH ROW 행 단위 처리만 지원FOR EACH ROW)FOR EACH STATEMENT) 모두 지원NEW은 새로 입력되는 값, OLD는 기존 값TRUNCATE는 트리거가 실행되지 않음(대부분의 DBMS). 트랜잭션 제어문(명시적 COMMIT/ROLLBACK)은 트리거 내부에서 금지되는 경우가 많음.1. 테이블 설계
CREATE TABLE member (
id CHAR(36) PRIMARY KEY,
email VARCHAR(255) UNIQUE,
name VARCHAR(100),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE member_deleted (
id CHAR(36),
email VARCHAR(255),
name VARCHAR(100),
deleted_at DATETIME,
original_created_at DATETIME,
PRIMARY KEY (id, deleted_at)
);
2. 트리거 생성 (SQL)
DELIMITER $$
CREATE TRIGGER trg_member_after_delete
AFTER DELETE ON member
FOR EACH ROW
BEGIN
INSERT INTO member_deleted (
id, email, name, deleted_at, original_created_at
)
VALUES (
OLD.id, OLD.email, OLD.name, NOW(), OLD.created_at
);
END$$
DELIMITER ;
TRUNCATE 명령어는 트리거를 발생시키지 않음 (대부분의 DBMS에서 적용 안 됨)
트리거 내부에서는 명시적 트랜잭션 제어 불가
트리거 내부에서 부작용이 큰 로직 (예: 외부 API 호출, 복잡한 쿼리 반복 등)은 지양해야 함