오래 못 할 짓 하지 않기

[ 데이터베이스 ] 12. Trigger 본문

3학년 1학기/데이터베이스(DB)

[ 데이터베이스 ] 12. Trigger

쫑알bot 2024. 1. 9. 17:52
728x90

Trigger

 

: DB에서 어떤 이벤트가 발생하면 실행되는(Trigger되는) Procedure

                = Insert  Update  Delete

 

예) USERS 테이블에 있는 사용자의 닉네임을 바꾸면

      USERS_LOG 테이블에 이전 닉네임 + 언제까지 썼는지 업데이트하기

  

delimiter $$

▶ Create TRIGGER log_user_nickname_trigger       

Before UPDATE                                                     // 언제 발생시킬거냐? = Update가 일어났을 때     

▶ On users FOR EACH ROW                // users 테이블에서 변화가 발생하면 , Update가 되는 각 row에 대해 trigger 실행

 

▶ Begin   //프로시저 body에는 trigger 조건이 되었을 때 어떤 걸 실행할지 정한다.                                           

▶              insert into users_log values(OLD.id, OLD.nickname, now());   // OLD = update되기 전의 tuple ,

                                                                                                                  //만약 trigger 가 delete면 delete된 tuple을 가져옴

▶ END

▶ $$

 

 

Before : update 되기 전에 해라

After 면?  -> update 되고 나서 해라 

 

 



예) 사용자가 마트에서 상품을 구매하면
누적된 구매 비용 구하는 트리거 작성하기

delimiter $$

▶ Create TRIGGER price_add_trigger

After Insert   

▶ On Buy for each row

▶ Begin

           Declare total INT;

           Declare user_id INT DEFAULT NEW.user_id;    //방금 구매가 이루어진 사용자를 user_id로 넣는다.

           Select sum(price) into total from buy where user_id=user_id;   // 총 구매 비용이 얼마인지 구해놓고 total에 넣음

▶            update User_buy_stats set price_sum = total where user_id = user_id; 

                // user_buy stats 테이블에서, user_id가 같은 곳에 있는 price_sum을 total값으로 세팅한다.

▶ End

▶ $$

 

After 오고 난 뒤에 NEW 는 insert나 update된 후의 tuple을 가리킨다.

 


여러 개의 변화를 한 번에 감지할 수도 있다

 

위와 같은 명령어를 실행했다고 해보자

여기에서 주의깊게 보아야 하는 건 [ FOR EACH ROW ] 인데

 

이런 경우에는 한 행이 [ 삽입 / 변경 / 삭제 ] 된다 → 정해진 Procedure 실행

이다.

 

그럼 만약 위와 같은 Trigger가 있을 때 

Update employee SET salary = 1.5 * salary Where dept_id = 1003; 

이렇게 부서 id가 1003인 직원들의 연봉을 1.5배 해주는 SQL문을 실행했을 때

업데이트 되는 직원이 5명이면 Trigger도 5번 실행된다.

 

이런 비효율을 줄이고자 만들어진 것이

FOR EACH ROW    →    FOR EACH STATEMENT로 바꾸는 것이다. (Mysql은 안 됨)

 

 

When

FOR EACH (ROW or STATEMENT) 다음에

WHEN 절을 넣어서 조건을 걸어줄 수 있다.

 

우리가 위에서 했던 예시로

닉네임을 바꿀 때 업데이트를 한다고 보자

새로 들어오는 닉네임과 기존 닉네임이 달라야 Trigger가 발생한다고 설정을 하려면

위와 같이 만들 수 있다.

 



주의 사항

1. 소스 코드로는 발견할 수 없는 로직 ( DB에 존재하기 때문에 )

    → 문제가 생겼을 때 대응이 힘들다.

    → 가시적이지 않아서 개발 / 관리 / 문제 파악이 힘들다.

 

 

2. 과도한 트리거 사용은 DB에 부담 → 응답이 느려짐

 

 

요약

: 사용을 최대한 피한다

그냥 회사에서 쓰는 룰대로 해라

 

 

 

 (출처)

유튜브 쉬운코드