본문 바로가기

공부 기록/Database

Trigger

Trigger

- DB에서 어떤 이벤트가 발생했을 때 자동적으로 실행되는 프로시저
- 데이터에 변경이 생겼을 때, 즉 DB에 insert, update, delete가 발생했을 때 이것이 계기가 되어 자동적으로 실행되는 프로시저를 의미한다.


사용자의 닉네임 변경 이력을 저정하는 트리거

table => users(id, nickname) / users_log(id, nickname, until)

delimiter $$
CREATE TRIGGER log_user_nickname_trigger
BEFORE UPDATE
ON users FOR EACH ROW
BEGIN
ㅤㅤinsert into users_log values(OLD.id, OLD.nickname, now());
END
$$
delimiter ;

- "BEFORE" UPDATE

- OLD : update 되기 전의 tuple 또는 delete된 tuple을 가리킨다.


사용자가 마트에서 상품을 구매할 때마다 지금까지 누적된 구매 비용을 구하는 트리거

table => buy(id, user_id, price, buy_at) / user_buy_stats(user_id, price_sum)

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;
ㅤㅤ
ㅤㅤ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 ;

- "AFTER" INSERT

- NEW : insert된 tuple 또는 update된 후의 tuple을 가리킨다.


참고 (MySQL은 불가능)

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

- trigger를 정의할 때, update, insert, delete 등을 한 번에 감지하도록 설정할 수 있다.

- FOR EACH "STATEMENT"
   - row 단위가 아니라 statement 단위로 trigger가 실행될 수 있도록 할 수 있다.
   - UPDATE를 실행할 때 다섯 명의 연봉이 UPDATE되어도 trigger는 한 번만 실행된다.

 

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();

- trigger를 발생시킬 디테일한 조건을 지정할 수 있다.


주의 사항

- 소스 코드로는 발견할 수 없는 로직이기 때문에 어떤 동작이 일어나는지 파악하기 어렵고 문제가 생겼을 때 대응하기 어렵다.
- 가시적이지 않아서 개발, 관리, 문제 파악이 힘들다.

- 과도한 트리거 사용은 DB에 부담을 주고 응답을 느리게 만든다.

- 디버깅이 어렵다.

- 문서 정리가 특히 중요하다.

'공부 기록 > Database' 카테고리의 다른 글

Database Transaction & ACID  (0) 2024.01.20
Stored Procedure  (0) 2023.11.12
Three-tier architecture  (0) 2023.07.30
Stored Function  (0) 2023.07.26
Spring Data MongoDB 적용해보기  (0) 2023.06.28