펜타시스템/입사 후 첫 프로젝트 공부 내용

첫 과제 Cubrid → NIFI → HDFS 구조 재현하기 - 테이블, 트리거 설계

dev-lee 2026. 9. 11. 15:24

1. 파이프라인 구조와 더미·트리거 테이블의 역할

큐브리드 원본 테이블에서 필요한 컬럼만 추려 더미 테이블을 만들고, 트리거로 변경 이력을 트리거 테이블에 적재해 NiFi가 폴링·HDFS 적재하는 구조를 다룸.

1.1 전체 흐름

  • 원본 테이블 — tb_cntr_dclr_mng_bfr_prcs 등 운영 테이블에서 필요한 컬럼만 선별함
  • 더미 테이블 — CTAS(CREATE TABLE AS SELECT)로 원본 구조를 복제하되 데이터는 비운 상태로 생성함. 실제 적재는 별도 파이썬 데이터 생성기가 담당함
  • 트리거 테이블 — 더미 테이블에 INSERT/UPDATE가 발생하면 트리거가 호출되어 변경 이력(테이블명, PK값, 변경유형, 변경일시)을 기록함
  • NiFi 폴링 — 트리거 테이블을 주기적으로 조회해 미처리 건을 가져감
  • HDFS 적재 — NiFi가 가져온 데이터를 HDFS에 put함

1.2 더미 테이블과 트리거 테이블의 역할 구분

두 테이블은 목적이 명확히 분리됨.

구분  더미 테이블 (test_dmy_table) 트리거 테이블 (test_trigger_table)
역할 실제 업무 데이터를 흉내낸 원본 역할 변경 이력(CDC 로그) 저장
PK 원본 테이블의 PK(mng_no) 그대로 사용 별도 AUTO_INCREMENT(trig_id)
적재 방식 파이썬 생성기로 더미 데이터 삽입/수정 트리거에 의해 자동 삽입
소비 주체 트리거의 감시 대상 NiFi가 폴링하는 대상

더미 테이블은 "무엇이 바뀌었는지"를 담고, 트리거 테이블은 "무엇이, 언제, 어떻게 바뀌었는지"를 담는 로그 역할로 나뉨.


2. 트리거(Trigger) 설계

큐브리드 트리거의 이벤트 시점, 이벤트 타입, 코멘트, 실행 영역 개념을 정리함.

2.1 트리거 이벤트 시점 — BEFORE / AFTER / DEFERRED

시점  동작 시점 주 용도
BEFORE 이벤트 처리 전 특정 조건에서 이벤트 자체를 막는 검증·방지 용도
AFTER 이벤트(INSERT, UPDATE 등) 처리 후 처리 직후 후속 작업(로그 적재 등) 수행
DEFERRED 커밋 이후 트랜잭션이 완전히 확정된 뒤 이벤트를 트리거

이번 설계에서는 INSERT/UPDATE가 수행되는 즉시 트리거 테이블에 이력을 남겨야 하므로 AFTER를 채택함.

2.2 트리거 이벤트 타입과 대상

  • 이벤트 타입 — 인스턴트 이벤트로 INSERT, UPDATE, DELETE가 있으며, 이번 설계에서는 DELETE를 제외하고 INSERT·UPDATE만 감지함
  • 이벤트 대상 — 이벤트 타입과 테이블을 조합해 지정함. 예를 들어 UPDATE ON 테이블명으로 지정하면 해당 테이블에 UPDATE문이 실행될 때 트리거가 호출됨

2.3 트리거 코멘트(Trigger Comment)

  • COMMENT 절 — 트리거가 어떤 역할을 하는지 문서화하는 용도로 사용함
  • ;sc 명령어 — 등록된 트리거의 코멘트를 조회할 때 사용함

2.4 트리거 실행 영역 — IF condition / EXECUTE action

IF <condition>
EXECUTE <action>
  • IF — 트리거가 수행될 조건을 기술하는 영역
  • EXECUTE — 조건을 만족했을 때(또는 조건이 없을 때 이벤트 발생 즉시) 수행할 동작을 기술하는 영역

3. 테이블·트리거 구현

실제 CUBRID DDL로 트리거 테이블, 더미 테이블, INSERT/UPDATE 트리거, 시퀀스를 구현한 내용을 정리함.

3.1 트리거 테이블 생성

CREATE TABLE test_trigger_table (
    trig_id          INT             AUTO_INCREMENT,
    tbl_nm           VARCHAR(100)     NOT NULL,
    pk_vl            VARCHAR(200)    NOT NULL,
    trig_type_cd     CHAR(1)         NOT NULL,
    chg_dt           DATETIME        NOT NULL,
    job_id           VARCHAR(100),
    job_proc_dt      DATETIME,
    job_prcs_stts_cd CHAR(1)         DEFAULT '0',
    PRIMARY KEY (trig_id)
);
  • trig_id — AUTO_INCREMENT PK. 트리거 테이블 자체의 식별자로 원본 PK와 무관하게 발급됨
  • tbl_nm, pk_vl — 변경이 발생한 원본(더미) 테이블명과 해당 행의 PK값을 문자열로 저장해 어떤 테이블의 어떤 레코드가 바뀌었는지 추적함
  • trig_type_cd — 'i'(insert), 'u'(update)로 변경 유형을 구분함
  • chg_dt — 변경이 발생한 시각을 기록함
  • job_id, job_proc_dt, job_prcs_stts_cd — NiFi가 폴링해 처리할 때 사용할 작업 식별자·처리 시각·처리 상태 컬럼. 기본값 '0'은 미처리 상태를 의미함

3.2 더미 테이블 생성

CREATE TABLE test_dmy_table
AS SELECT 
mng_no, 
rcpt_no, 
img_seqn, 
msg_id, 
cvlpr_telno, 
mclsf_nm, 
sclsf_nm, 
incdnt_ocrn_dt, 
sndpy_telno_cn,
dscsn_cn,
ltr_cn,
data_stts_cd,
ahfl_id,
bfr_prcs_yn,
frst_rgtr_id,
last_mdfcn_dt,
last_mdfr_id
FROM tb_cntr_dclr_mng_bfr_prcs
WHERE 1=0;
ALTER TABLE test_dmy_table ADD CONSTRAINT PRIMARY KEY (mng_no);
  • CTAS(WHERE 1=0) — 원본 테이블(tb_cntr_dclr_mng_bfr_prcs)에서 필요한 컬럼만 선택해 구조만 복제하고 데이터는 가져오지 않음
  • PK 별도 추가 — CTAS로 생성한 테이블은 제약조건이 함께 복제되지 않으므로, 이후 ALTER TABLE로 PK를 별도 지정함
  • 실제 더미 데이터 적재는 파이썬으로 구축할 생성기가 담당할 예정임

3.3 INSERT/UPDATE 트리거 구현

CREATE TRIGGER test_ins_trigger IF NOT EXISTS
AFTER INSERT ON test_dmy_table
EXECUTE INSERT INTO test_trigger_table (tbl_nm, pk_vl, trig_type_cd, chg_dt)
VALUES ('test_dmy_table', test_dmy_table.mng_no, 'i', SYS_DATETIME)
COMMENT 'trigger for my study';

CREATE TRIGGER test_upt_trigger IF NOT EXISTS
AFTER UPDATE ON test_dmy_table
EXECUTE INSERT INTO test_trigger_table (tbl_nm, pk_vl, trig_type_cd, chg_dt)
VALUES ('test_dmy_table', test_dmy_table.mng_no, 'u', SYS_DATETIME)
COMMENT 'trigger for my study';
  • IF NOT EXISTS — 동일한 이름의 트리거가 이미 있으면 재생성을 생략함
  • AFTER INSERT / AFTER UPDATE ON test_dmy_table — 더미 테이블에 각각 INSERT, UPDATE가 발생한 직후 호출됨
  • EXECUTE INSERT INTO test_trigger_table — 트리거 테이블에 변경 이력 한 건을 적재함. test_dmy_table.mng_no로 방금 변경된 행의 PK를 참조함
  • trig_type_cd — INSERT 트리거는 'i', UPDATE 트리거는 'u'로 구분해 적재함
  • SYS_DATETIME — 트리거 실행 시점의 시스템 시각을 chg_dt에 기록함

두 트리거 모두 EXECUTE 절 하나로 단순 INSERT만 수행하므로, 별도 IF 조건 없이 이벤트 발생 즉시 실행되는 구조임.

3.4 더미 데이터 PK 중복 문제와 시퀀스

CREATE SERIAL dummy_mng_no_seq START WITH 1 INCREMENT BY 1;
  • 더미 테이블에 데이터를 채울 때 원본 테이블에서 랜덤 샘플링해 계속 가져올 예정이므로, mng_no를 그대로 사용하면 PK 중복이 발생할 수 있음
  • 이를 방지하기 위해 별도 시퀀스(dummy_mng_no_seq)를 생성해 더미 테이블 삽입 시 새로운 PK 값을 발급하도록 함

요약

구성 요소 역할
더미 테이블 (test_dmy_table) 원본 테이블 구조를 복제한 테스트용 원본. INSERT/UPDATE 감지 대상
트리거 테이블 (test_trigger_table) 변경 이력(테이블명·PK·변경유형·시각·처리상태)을 적재하는 로그 테이블
AFTER INSERT/UPDATE 트리거 이벤트 처리 직후 트리거 테이블에 이력 한 건을 적재
SERIAL(dummy_mng_no_seq) 랜덤 샘플링으로 인한 PK 중복을 방지하는 별도 시퀀스

더미 테이블과 트리거 테이블을 분리해 "데이터"와 "변경 이력"의 책임을 나누고, AFTER 트리거로 변경 즉시 이력을 남겨 NiFi가 트리거 테이블만 폴링해도 변경분을 놓치지 않도록 설계함.