0Pricing
SQL Academy · 강의

트리거로 테이블 감사하기

AFTER INSERT/UPDATE/DELETE 트리거를 사용해 audit_log 테이블에 기록을 남기는 감사 추적을 구축해보세요.

트리거로 테이블 감사하기은(는) CoddyKit의 무료 SQL Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

감사가 필요한 이유

감사 기록은 "누가, 무엇을, 언제 변경했는가"에 답합니다. 규정 준수(HIPAA, SOX, GDPR의 삭제 권리 관련 조사)에 필요하며 운영 포렌식에도 사용됩니다.

감사 테이블

하나의 중앙 테이블에서 모든 변경을 기록합니다:

CREATE TABLE audit_log (
  id BIGSERIAL PRIMARY KEY,
  ts TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  user_name TEXT NOT NULL DEFAULT CURRENT_USER,
  table_name TEXT NOT NULL,
  action TEXT NOT NULL,             -- INSERT, UPDATE, DELETE
  row_id TEXT,
  old_data JSONB,
  new_data JSONB
);

감사 트리거 함수

여러 테이블에서 재사용할 수 있는 하나의 함수입니다:

CREATE OR REPLACE FUNCTION audit_row()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO audit_log (table_name, action, row_id, old_data, new_data)
  VALUES (
    TG_TABLE_NAME,
    TG_OP,
    COALESCE(NEW.id::TEXT, OLD.id::TEXT),
    CASE WHEN TG_OP IN ('UPDATE','DELETE') THEN to_jsonb(OLD) END,
    CASE WHEN TG_OP IN ('INSERT','UPDATE') THEN to_jsonb(NEW) END
  );
  RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

테이블에 연결하기

AFTER INSERT/UPDATE/DELETE에 트리거를 설정합니다:

CREATE TRIGGER trg_audit_users
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION audit_row();

to_jsonb(NEW)

to_jsonb 기법은 열별 코드를 작성하지 않고 전체 행을 일반적으로 기록합니다. id 열이 있는 모든 테이블에서 작동합니다.

작업 주체 추적

앱이 하나의 DB 사용자로 실행된다면 현재 사용자만으로는 충분하지 않습니다. 세션 GUC를 통해 앱 사용자를 전달하십시오:

-- App sets:
SET LOCAL app.user_id = '42';

-- Trigger reads:
INSERT INTO audit_log (... actor_id ...) VALUES (..., current_setting('app.user_id', true)::BIGINT);

특정 열 감사

선택적으로 감사하려면 트리거 WHEN 절을 사용하십시오:

CREATE TRIGGER trg_audit_role_change
AFTER UPDATE OF role ON users
FOR EACH ROW WHEN (OLD.role IS DISTINCT FROM NEW.role)
EXECUTE FUNCTION audit_role_change();

테이블별 감사 테이블

대안으로 실제 테이블마다 동일한 스키마와 감사 메타데이터를 가진 감사 테이블(예: users_audit)을 하나씩 만들 수 있습니다. 쿼리하기는 더 쉽지만 유지 관리해야 할 DDL이 더 많습니다.

변경분만 감사하기

변경된 열만 저장합니다:

INSERT INTO audit_log (table_name, action, changes)
VALUES (
  TG_TABLE_NAME, TG_OP,
  (SELECT jsonb_object_agg(key, value)
   FROM jsonb_each(to_jsonb(NEW))
   WHERE NEW.* IS DISTINCT FROM OLD.* AND to_jsonb(NEW)->key IS DISTINCT FROM to_jsonb(OLD)->key)
);

감사 테이블 성능

사용량이 많은 시스템에서는 감사 테이블이 빠르게 커집니다. 시간 기준으로 파티셔닝하십시오:

CREATE TABLE audit_log (...) PARTITION BY RANGE (ts);
CREATE TABLE audit_log_2024_q1 PARTITION OF audit_log
  FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');

성능 절충

이제 각 insert/update/delete가 두 번째 행도 기록합니다. 쓰기가 매우 많은 테이블에서는 IO가 두 배가 될 수 있습니다. 테스트하고 모니터링한 뒤 이 절충이 가치 있는지 결정하십시오.

DB 트리거를 사용하지 않을 때

이벤트 버스 연동이 필요하다면 트리거 대신 NOTIFY 또는 LISTEN으로 이벤트를 대기열에 넣거나 논리적 복제 및 CDC 도구(Debezium)를 사용하십시오.

복습

감사 트리거는 변경 이력을 기록하는 가장 간단한 방법입니다.

  • to_jsonb(NEW/OLD)를 사용하는 하나의 일반 함수
  • 감사할 모든 테이블에 연결
  • 감사 테이블을 시간 기준으로 파티셔닝
  • GUC를 통해 앱의 작업 주체를 명시적으로 추적

빠른 확인

감사 트리거 함수 내부에서 새 행을 일반적인 JSONB로 캡처하려면 어떻게 해야 합니까?

자주 묻는 질문

“트리거로 테이블 감사하기” 강의는 무료인가요?

네 — “트리거로 테이블 감사하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Academy 강의 전체를 잠금 해제할 수 있습니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“트리거로 테이블 감사하기”에서 뭘 배우나요?

AFTER INSERT/UPDATE/DELETE 트리거를 사용해 audit_log 테이블에 기록을 남기는 감사 추적을 구축해보세요. 브라우저에서 직접 실행하는 실습 코드로 SQL Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

SQL Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 SQL Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“트리거로 테이블 감사하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 SQL Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 SQL Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 트리거 구조: BEFORE/AFTER, FOR EACH ROW
  2. PL/pgSQL 함수 기초
  3. DO 블록과 익명 코드
  4. 트리거로 테이블 감사하기
← SQL Academy(으)로 돌아가기