프로그래밍데이터베이스 엔지니어 / DBA

SQL에서 트리거의 작동 원리를 설명하고, 장단점 및 일반적인 사용 시나리오를 설명하세요. 실제 트리거의 예를 제공하세요.

Hintsage AI 어시스턴트로 면접 통과

답변

트리거 — 특정 코드(일반적으로 SQL 또는 PL/pgSQL과 같은 절차적 확장 언어로 작성된)의 실행을 자동으로 시작하는 데이터베이스의 특별한 객체입니다. 이 코드는 테이블에서 INSERT, UPDATE 또는 DELETE 이벤트가 발생할 때 실행됩니다.

장점:

  • 비즈니스 로직과 데이터 유효성 검사를 중앙 집중적으로 적용할 수 있습니다.
  • 감사 작업의 자동화(예: 변경 이력).

단점:

  • 숨겨진 실행 — 트리거가 실행되었다는 것이 항상 명확하지 않습니다.
  • 테이블의 빈번한 변경 시 성능 저하.
  • 디버깅의 복잡성과 무한 루프(재귀 트리거)의 위험.
  • 데이터 마이그레이션이 복잡해집니다.

적용할 때:

  • 데이터 감사.
  • 관련 레코드의 자동 생성.
  • 표준 방법으로는 불가능한 제약 조건의 적용.

트리거 예제 (PostgreSQL):

CREATE TABLE employee_audit ( id SERIAL PRIMARY KEY, employee_id INT, old_salary NUMERIC, new_salary NUMERIC, changed_at TIMESTAMP ); CREATE OR REPLACE FUNCTION audit_salary() RETURNS TRIGGER AS $$ BEGIN IF NEW.salary <> OLD.salary THEN INSERT INTO employee_audit(employee_id, old_salary, new_salary, changed_at) VALUES (OLD.id, OLD.salary, NEW.salary, NOW()); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_salary_update AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION audit_salary();

함정 질문

트리거 내부에서 자신이 설정된 동일한 테이블을 업데이트할 수 있나요? 무슨 일이 일어날까요?

답변:
트리거가 테이블의 UPDATE 이벤트로 설정되어 있고 내부에서 이 동일한 테이블에 대해 또 다른 UPDATE를 수행하는 경우 무한 재귀(루프)가 발생하여 명령이 비정상적으로 종료되거나 트리거 깊이 초과 오류가 발생합니다. 따라서 재귀가 발생하지 않도록 항상 제어하거나 재귀 호출을 허용/금지하는 설정을 사용해야 합니다.

예제:

-- 이 구조로 트리거를 루프에 빠뜨릴 수 있습니다: CREATE OR REPLACE FUNCTION recursive_update() RETURNS TRIGGER AS $$ BEGIN UPDATE employees SET salary = salary * 1.01 WHERE id = NEW.id; -- 다시 작동할 것입니다 RETURN NEW; END; $$ LANGUAGE plpgsql;

사례

회계 CRM에 트리거를 도입하여 거래 테이블 변경 시 로그에 작업을 자동으로 기록하게 했습니다. 높은 부하에서 서비스가 느려졌고, 분석 결과 트리거가 로그에 삽입하는 데 많은 시간을 소모하며 최적화되지 않은 것을 확인했습니다(예: 중요한 이벤트만 기록).


사례

재고 관리 프로젝트에서 POSITION ID 계산을 위해 BEFORE INSERT 트리거를 사용했습니다. ID 오류로 인해 데이터 중복이 발생했으며, 트리거가 "뒤에서" 작동하기 때문에 오류가 오랫동안 눈에 띄지 않았습니다.


사례

HR 플랫폼에서 트리거가 매 삽입 시 부모 및 자식 테이블의 기록을 대량 업데이트했습니다. 트리거의 논리 오류로 인해 재귀가 발생해 모든 테이블 작업이 차단되었습니다. 트리거를 비활성화하고 테이블 잠금을 해제하기 위해 복잡한 롤백 절차를 수행해야 했습니다.