[SQL] - Trigger

오동훈·2023년 1월 20일
0

Database

목록 보기
37/39

1. Trigger

트리거(Trigger)는 테이블에서 어떤 이벤트가 발생했을 때 자동으로 실행되는 것을 의미합니다.

예를 들어, 어떤 테이블에서 특정한 이벤트 DML문(update, insert, delete)가 발생했을 때, 실행시키고자 하는 추가 쿼리 작업들을 자동으로 수행할 수 있게끔 트리거를 미리 설정해주는 것입니다.

정말 간략하게 예를 들어보자면, A 테이블에 1이라는 숫자가 입력됐을 때, 자동으로 B 테이블에도 1을 복사해주고 싶을 때 트리거를 이용해 설정해 놓았다면 자동으로 B에도 1이라는 숫자가 입력되게 할 수 있습니다.

2. Trigger 종류

1. 문장 트리거

  • INSERT, UPDATE, DELETE 문에 대해 한 번만 실행됩니다.
  • 삽입, 갱신 또는 삭제되는 행 수에 관계없이 각 트랜잭션에 대해 명령문 레벨 트리거가 한 번 실행됩니다.

BEFORE or AFTER : 트리거가 실행되는 시기를 지정해줍니다.

  • AFTER 트리거 : 쿼리 이벤트 작동한 후
  • BEFORE 트리거 : 쿼리 이벤트가 작동하기 전 -> 미리 데이터를 확인 가능할 때

2. 행 트리거

  • 테이블 안의 영향을 받은 행 각각에 대해 실행됩니다.
  • 변경 전 or 변경 후의 행은 각각 OLD, NEW라는 가상 줄 변수를 사용하여 읽을 수 있습니다.
    - OLD : 기존 데이터, delete로 삭제 된 데이터 또는 update로 바뀌기 전의 데이터
    - NEW : 새로운 데이터, insert로 삽입된 데이터 또는 update로 바뀐 후의 데이터
트리거 이벤트OLDNEW
INSERTXO
UPDATEOO
DELETEOX
  • INSERT - 새롭게 데이터가 추가되는 것이므로 이전 데이터는 존재하지 않아 OLD X, NEW O 입니다.
  • UPDATE - 기존에 있던 데이터를 새로운 데이터로 변경하는 작업이기 때문에 OLD O, NEW O 입니다.
  • DELETE - 기존에 있던 데이터를 지우는 작업이므로 OLD O, NEW X 입니다.

3. Trigger 사용법

1. 트리거 생성

DELIMITER $$

CREATE TRIGGER before_to_after -- before_to_after라는 Trigger 이름
AFTER INSERT ON before_num -- {BEFORE | AFTER} {INSERT | UPDATE | DELETE}중 언제 어떤 작업을 할 지 정해줍니다.
FOR EACH ROW -- 아래 나올 조건에 해당하는 모든 row에 적용한다는 의미

BEGIN
	-- Trigger가 실행되는 코드
	IF NEW.number THEN -- 새로운 number가 입력됐을 때,
		INSERT INTO after_num(id, number) VALUES(NEW.id, NEW.number); -- `VALUES(NEW.id, NEW.number)`의 데이터를 after_num의 id, number에 삽입
	END IF;
END $$
  • BEGIN ~ END 사이에 조건문과 실행문을 작성해줍니다.

2. 트리거 실행

Trigger before_to_after는 AFTER INSERT ON before_num가 실행되면 자동으로 트리거가 작동하는 구조이기 때문에, before_num 테이블에 새로운 데이터를 삽입해주면 됩니다.

INSERT INTO before_num(number) VALUES(1);

3. 기대 결과

위에서 만든 트리거 대로라면 before_num 테이블에 숫자를 입력하면 after_num에 자동으로 입력이 돼야 합니다. 그럼 한 번 확인해볼까요~

너무 단순해서 제가 입력한 거 같은데 이거 진짜 아니고 자동으로 삽입된 데이터입니다!

4. 트리거 확인

아래의 명령어를 입력하면 앞서 만들었던 Trigger 이름과 명령 등 정보들을 확인해 볼 수 있습니다.

show triggers;

5. 트리거 삭제

DELETE TRIGGERS;

6. 변수 생성

변수 선언은 DECLARE 명령을 이용해 사용하는데 이 또한 BEGIN ~ END 사이에 작성해주면 됩니다.

-- DECLARE 선언 방법 
BEGIN
	DECLARE 변수 타입 {디폴트값}
    .
    .
    .
END

7. 조건문

IF (조건) THEN
ELSEIF (조건) THEN
ELSE
ENDIF

8. 그래서 왜 썼는가

처음에는 이런 기능이 있는 줄 몰랐는데, 원래는 리스트 형태로 들어온 데이터를 DB에 그대로 저장해놓고, 해당 데이터를 다른 테이블에 골구로 컬럼별로 나눠 저장해주는 로직이 필요했습니다. 그래서 2가지 방안이 이야기가 나왔고 그게 바로 웹서버에서 처리하는 Celery 방식과 DB에서 처리하는 Trigger 방식입니다.

처음에는 Trigger 개념을 처음 들어봤고 ORM 사용해서 Celery 이용하면 금방할 수 있지 않을까라고 생각을 가지고 있었는데, 웹서버가 많은 데이터를 물고 있으면 그만큼 성능 리소스가 부족해질 수 있기 때문에 DB에서 처리하게 해주면 웹서버 성능 이슈가 낮아지게 돼 해당 Trigger 방법을 채택해 구현하게 되었습니다.

이로써 웹서버 부하 관리 방법 중 하나를 알게돼서 너무 좋습니다~~~ 히히

profile
삽질의 기록들🐥

0개의 댓글