트리거는 사전적 의미로 방아쇠를 뜻한다 방아쇠를 당기면 자동으로 총알이 나가듯이 트리거는 테이블에 무슨 일이 일어나면 자동으로 실행된다
즉 데이터에 변경이 생겼을 때 DB에 insert,update,delete가 발생 했을때 자동적으로 실행되는 프로시저를 의미한다
trigger를 정의할 때 알고 있으면 좋은 내용
1. update,insert,delete등을 한번에 감지하도록 설정가능하다
2. row 단위가 아니라 statement 단위로 trigger가 실행될 수 있도록 할 수 있다
FOR EACH ROW
- 변경된 튜플에 대해 트리거 실행
- 여러 튜플한번에 업데이트가 되었다면 여러번 실행되게 된다
FOR EACH STATEMENT
- 여러 튜플한번에 업데이트가 되면 한 번만 실행된다
3. trigger를 발생시킬 디테일한 조건을 지정할 수 있다
트리거 사용시 주의 사항
1. 소스 코드로는 발견할 수 없는 로직이기 때문에
어떤 동작이 일어나는지는 파악하기 어렵고 문제가 생겼을 때 대응하기 어렵다
(트리거가 많으면 하나를 업데이트를 했을 뿐인데 다른 데이터가 막 바뀌는데 찾기가 매우어렵다)
2. 과도한 트리거 사용은 DB에 부담을 주고 응답을 느리게 만든다
3. 디버깅이 어렵다
4. 문서 정리가 특히 중요하다
ex)
1. 사용자의 닉네임 변경이력을 저장하는 트리거
닉네임이 변경(update)되면 트리거가 작동하고 users_log에 과거 닉네임 저장
users
id | nickname |
1 | 피카츄 |
2 | ... |
users_log
id | nickname |
↓ ↓ ↓ ↓ ↓
users
id | nickname |
1 | 라이츄(변경) |
2 | ... |
업데이트 발생!!
트리거 실행
users_log
id | nickname |
1 | 피카츄 |
로그 테이블에 insert
트리거 제작
--트리거 생성
CREATE TRIGGER log_user_uickname_trigger -- 트리거 이름
BEFORE UPDATE --언제 이 트리거를 발생시킬지 (현재 닉네임이 변경되었을때이기 때문에 UPDATE로 설정)
--업데이트 이전에 이 트리거가 발생
ON users FOR EACH ROW -- 업데이트가 되는 각 로우에 대하여 실행하라 (FOR EACH ROW)
-- 어떤 테이블에서 이벤트가 발생했을때 (현재 users 테이블)
BEGIN --트리거가 어떤 액션을 취해야하는지 BEGIN으로 시작
--바디부분
insert into users_log values(OLD.id, OLD.nickname);
--로그 테이블에 insert한다
--OLD 키워드
--UPDATE 되기 전의 TUPLE가리킴
--DELETE된 TUPLE을 가리킴
END --END 끝
2. 사용자가 마트에서 상품을 구매할 때마다 지금까지 누적된 구매 비용을 구하는 트리거
BUY
ID | USER_ID | PRICE |
1 | 1 | 2000 |
... | ... | ... |
USER_BUY_STATS
USER_ID | PRICE_SUM |
1 | 2000 |
... | ... |
↓ ↓ ↓ ↓ ↓ ↓ ↓
BUY
ID | USER_ID | PRICE |
1 | 1 | 2000 |
... | ... | ... |
10 | 1 | 5000 |
구매 발생!!(INSERT)
트리거 실행
USER_BUY_STATS
USER_ID | PRICE_SUM |
1 | 7000 |
... | ... |
CREATE TEIGGER sum_buy_prices_trigger
AFTER INSERT -- INSERT 발생 이후
ON BUY FOR EACH ROW --BUY 테이블에
-- BUY 테이블에 INSERT 발생 이후 각 ROW에 대하여
--액션을 수행 시켜줘라
BEGIN
DECLARE total INT; --변수선언
DECLARE user_id INT DEFAULT NEW.user_id;
-- INSERT 발생한 튜플에 user_id를 user_id에 넣어줘라
--NEW
--INSERT 된 TUPLE을 가리킴
--UPDATE된 후의 TUPLE을 가리킴
select sum(price) into total from buy where user_id= user_id;
-- INTO 키워드를 사용해서 total 변수에 저장
update user_buy_stats set price_sum=total where user_id = user_id;
END
참고 유튜브
'DB' 카테고리의 다른 글
트리거 연습1 (0) | 2024.01.29 |
---|---|
DBeaver (0) | 2024.01.28 |
SQL함수 - 집계 함수 (0) | 2023.12.31 |
SQL함수 - 날짜 함수 (0) | 2023.12.29 |
SQL함수 - 문자열 함수 (2) | 2023.12.28 |