목차
트리거(Trigger)
트리거란 영어로 방아쇠라는 뜻입니다. 방아쇠를 당기면 총기 내부에서 알아서 일련의 작업을 실행하고 총알이 날아갑니다. 이와 같이 데이터베이스에서도 트리거는 특정 테이블에 INSERT, DELETE, UPDATE 와 같은 DML이 실행했을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램 입니다. 즉 사용자가 직접 호출하는 것이 아니라 데이터베이스에서 자동적으로 호출하는 것이 큰 특징입니다.
- 트리거는 데이터베이스 시스템에서 데이터의 삽입, 갱신, 삭제 등의 변경 이벤트가 발생했을 때 관련 작업이 자동으로 수행되게 하는 절차형 SQL(프로그램) 입니다.
- 이벤트는 전체 트랜잭션 대상과 각 행에 의해 발생되는 경우 모두를 포함할 수 있으며 테이블과 뷰, DB 작업을 대상으로 정의할 수 있습니다.
- 트리거는 데이터베이스에 저장되며, 데이터 변경 및 무결성 유지, 로그 메시지 출력등의 목적으로 사용됩니다.
- 트리거의 구문에는 DCL(데이터 제어어)을 사용할 수 없으며, DCL이 포함된 프로시저나 함수를 호출하는 경우에는 오류가 발생합니다.
트리거란 삽입, 갱신, 삭제 등의 변경 이벤트가 발생했을 때 관련 작업이 자동으로 수행하게 하는 절차형 SQL(프로그램) 입니다.
트리거의 장점
- 데이터 무결성의 강화합니다 (참조 무결성)
- 업무처리가 자동화 됩니다.
- 트리거를 사용하면 트랜잭션에 의해 자동으로 다른 명령을 일으킴으로 업무처리를 자동화 할 수 있습니다.
- 중간에 사용자가 개입하지 않고 구현된 규칙대로 알아서 실행됩니다.
트리거의 단점
- 트리거를 과도하게 사용하면 복잡한 상호 의존성을 초래할 수 있습니다.
- 예를 들면 하나의 트리거가 활성화되어 이 트리거 내의 SQL문이 수행되면 그 결과로 인해 다른 트리거가 활성화되어 그 트리거의 SQL 문이 수행될 수 있습니다. (트리거 연쇄)
트리거의 종류
행 트리거, 문장 트리거 2가지 종류가 있습니다.
- 행 트리거 : 데이터의 변화가 생길 때마다 실행합니다.
- 문장 트리거 : 트리거에 의해 단 한 번 실행 합니다.
트리거의 구성
- 프로시저나 사용자 정의함수와 기본적 문법은 같습니다.
- 반환 값이 없고, DML을 주된 목적으로 한다는 점에서 프로시저와 비슷합니다.
- 트리거 실행을 위한 이벤트를 인지하기 위해 EVENT 명령을 사용합니다.
- 외부 변수 IN / OUT 이 없습니다.
트리거나느 다음과 같이 트리거는 선언부, 이벤트부, 시작/종료부, 제어부, 예외부로 구성되어 있습니다.
각각의 대략적인 역할은 다음과 같습니다.
구성요소 | 설명 |
선언부(DECLARE) | 트리거의 명칭을 정의하는 부분 입니다. |
이벤트부(EVENT) | 트리거가 실행되는 타이밍, 이벤트를 명시하는 부분입니다. |
시작 / 종료부 (BEGIN / END) | 트리거의 시작과 종료를 표현하며, BEGIN / END 가 쌍을 이룹니다. 다수 실행을 제어하는 기본적 단위가 되며 논리적 프로세스를 구성합니다. |
제어부(CONTROL) | 기본적으로 순차적으로 처리합니다. 비교 조건에 따라 블록 또는 문장을 실행합니다. 조건에 따라 반복 실행합니다. |
SQL | DML을 주로 사용합니다. 자주 사용되진 않지만 DDL(CREATE, ALTER, DROP, TRUNCATE)을 사용합니다. |
에외부(EXCEPTION) | BEGIN ~ END 절에서 실행되는 SQL문에서 예외 발생시 예외 처리 방법을 정의합니다. |
이제 하나씩 살펴보도록 하겠습니다.
선언부
트리거를 생성하고 명칭을 선언합니다.
CREATE TRIGGER 트리거명
CREATE OR REPLACE TRIGGER 트리거명
구성 | 설명 |
CREATE | DBMS 내에 객체(트리거, 함수, 프로시저)를 생성합니다. OR REPLACE는 기존 프로시저가 존재 시 현재 컴파일 하는 내용으로 덮어씁니다. (같은 이름의 프로시저가 존재할 경우 OR REPLACE가 없으면 에러가 발생합니다.) |
TRIGGER | 트리거(TRIGGER)를 사용한다는 의미입니다. |
트리거명 | 해당 트리거를 나타내는 이름입니다. |
이벤트부(TRIGGER)
트리거가 실행되는 타이밍읠 명시하는 부분 입니다.
양식
순서 이벤트 ON 테이블명 [FOR EACH ROW]
1. 순서 : BEFORE, 이벤트 : 하나의 이벤트(INSERT)
BEFORE INSERT ON TABLE_NAME
2. 순서 : AFTER, 이벤트 : 여러 이벤트(INSERT, DELETE)
AFTER INSERT OR DELETE ON TABLE_NAME
3. 순서 : AFTER, 이벤트 : 하나의 이벤트(INSERT)
AFTER INSERT ON TABLE_NAME
FOR EACH ROW -- 변경되는 데이터 행의 수만큼 실행, INSERT, DELETE는 FOR EACH ROW 없이 사용할 수 없음
시작 / 종료부 (BEGIN / END)
트리거의 실행 시작과 종료를 알려주는 부분으로 프로시저에 따라 BEGIN, END는 프로시저에 반드시 포함되어야 합니다.
제어부
단위 블록별 실행흐름을 제어하는 부분으로 크게 IF문과 CASE 문으로 나누어 집니다.
SQL
DML을 주로 사용하며 어떤 작업을 할 것인지 나타내는 부분 입니다.
- SELECT, INSERT, UPDATE, DELETE를 주로 사용합니다.
- 행 트리거 안에서 접두어를 붙여 OLD(데이터 변경 전) NEW(데이터 변경 후) 값을 참조합니다.
데이터 작업 | OLD | NEW |
INSERT | NULL | 삽입 후 값 |
UPDATE | 갱신 전 값 | 갱신 후 값 |
DELETE | 삭제 전 값 | NULL |
예외부(EXCEPTION)
트리거 실행 중 발생 가능한 예외 상황을 수행하는 부분 입니다.
반드시 포함될 필요는 없습니다.
트리거의 예시
이번에는 직접 트리거를 생성해보고 잘 작동되는지 확인해보도록 하겠습니다.
다음과 같은 시나리오를 준비해 봤습니다.
1. user 테이블과 user_backup 테이블 생성
2. user 테이블의 데이터가 삭제되면 user_backup 테이블에 삭제된 데이터가 저장되는 트리거 생성
3. user 테이블의 데이터를 삭제할 때 user_backup 테이블에 저장되는지 확인해 트리거가 잘 작동되는지 확인
위의 시나리오를 구성하기 위해 MariaDB를 사용했고 study라는 데이터베이스를 새로 생성했습니다.
테이블 생성
create 문을 통해 user 테이블과 user_backup 테이블을 생성합니다.
CREATE TABLE user (
user_id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(20),
user_address VARCHAR(50),
user_phone VARCHAR(15)
)
CREATE TABLE user_backup (
user_backup_id INT PRIMARY KEY AUTO_INCREMENT,
user_backup_name VARCHAR(20),
user_backup_address VARCHAR(50),
user_backup_phone VARCHAR(15)
)
테이블이 생성된 걸 확인할 수 있습니다.
데이터 삽입
user 테이블에 데이터를 삽입합니다.
INSERT INTO user VALUE(1, "조씨", "3호선 끝", "01085" );
INSERT INTO user VALUE(2, "김씨", "5호선 끝", "01050" );
데이터가 삽입된 걸 확인할 수 있습니다.
트리거 생성
user 테이블의 행이 삭제될 때 user_backup 테이블로 데이터가 저장되는 트리거를 생성합니다.
-- 트리거 생성
DELIMITER //
CREATE TRIGGER user_backup_trigger
AFTER DELETE -- 삭제 되면 작동
ON user -- 어떤 테이블? user 테이블
FOR EACH ROW -- 각 행(row) 마다 적용
BEGIN -- 테이블에 백업데이터 삽입
INSERT INTO user_backup VALUE(OLD.user_id, OLD.user_name, OLD.user_address, OLD.user_phone);
END
DELIMITER ;
DELIMITER //
: 문장 구분자를 "//"로 설정한다는 뜻 입니다. 원래 명령문 또는 쿼리를 사용할 때 세미콜론(;)으로 구분하는데 Trigger 생성시 IF 문등에서 ';'를 사용하려고 구분자를 // 로 변경한 것 입니다.
CREATE TRIGGER user_backup_trigger
: CREATE TRIGGER [ 트리거 이름 ]
AFTER DELETE ON sale_table
: AFTER DELETE ON [변경을 감지할 테이블]
해당 테이블에 DELETE 이벤트가 실행된 후
FOR EACH ROW
: 아래 나올 조건에 해당하는 모든 row 에 적용한다는 뜻 입니다.
BEGIN ~ END
: BEGIN 과 END 사이의 조건문과 실행문을 작성합니다.
user 테이블의 변경 전 / 후 를 기준으로 필드 앞에 변경 전은 OLD, 변경 후에는 NEW 키워드가 붙습니다.
OLD.user_id 는 삭제전의 user_id를 의미하고 삭제될 데이터를 백업테이블에 저장할 수 있습니다.
이렇게 Trigger를 생성하고 나면 구분자가 // 로 되어있기 때문에
DELEMITER ; 를 통해 다시 구분자를 원래대로 복원시킵니다.
위의 SQL을 실행하면 트리거가 생성됩니다.
트리거 확인
트리거가 잘 작동되는지 확인하기 위해 user 테이블에 데이터를 삭제해보겠습니다.
DELETE FROM user WHERE user_name = "조씨"
위의 SQL을 실행하면 user 테이블에 데이터가 삭제됩니다.
삭제된 조씨는 user_backup 테이블에 저장되 있는 것을 확인할 수 있습니다.
트리거 삭제
다음은 트리거 삭제에 대해 알아보겠습니다.
DROP 명령어를 통해 삭제할 수 있습니다.
DROP TRIGGER IF EXISTS user_backup_trigger
후기
이번에는 면접 때 질문 받은 트리거에 대해 공부하고 포스팅해보았습니다.
그 당시에는 제대로 답변을 못했는데 공부하고 간단하지만 직접 구현해 실행해보니 다음 번에는 더 잘 대답할 수 있을 거 같은 느낌이 듭니다.
포스팅은 여기서 마치겠습니다. 좋은 하루 되세요~
참조 사이트
https://benggri.tistory.com/78
[DB] 트리거(Trigger)
트리거(Trigger) 특정 테이블에 삽입, 수정, 삭제 등의 데이터 변경 이벤트가 발생하면 DBMS에서 자동적으로 실행되도록 구현된 프로그램입니다. 이벤트는 전체 트랜잭션 대상과 각행에 의해 발생
benggri.tistory.com
https://woo-dev.tistory.com/28
[MariaDB,MySQL] Trigger 사용법 / 특정 테이블 변경 시 관련 테이블 이벤트 실행
Trigger는 지정된 테이블의 변경을 감지하여 INSERT / UPDATE / DELETE 이벤트가 일어났을 때 설정한 이벤트를 실행하도록 합니다. 예를 들어, A테이블의 어떤 row의 name 필드의 값이 UPDATE 되면 B테이블의 n
woo-dev.tistory.com
https://runcoding.tistory.com/32
[DB] Trigger 트리거 개요 및 장단점
데이터베이스 트리거 트리거 ( Trigger )는 테이블에 대한 이벤트에 반응해 자동으로 실행되는 작업을 의미합니다. 트리거는 DML의 데이터 상태 관리를 자동화하는 데 사용됩니다. EX ) 데이터의 입
runcoding.tistory.com