금융위원회 2026년 9월 11일 시행 제도의 데이터 모델링
이서현 · 이채원
사망신고를 해도 은행이 그 사실을 알기까지 최대 두 달이 걸렸습니다.
기존에는 행정안전부의 사망자 정보가 월 1회, 그것도 일부 금융회사에만 제공됐습니다. 사망신고 기한 1개월과 합쳐지면 공백이 두 달까지 벌어집니다.
사망자 명의 계좌에서 인출과 이체가 계속 가능합니다. 상속인 간 분쟁, 명의도용 범죄의 통로가 됩니다.
보도자료의 각 문장이 어떤 테이블과 제약으로 바뀌었는지 대응시켰습니다.
| 제도 내용 | DB에서 표현해야 할 것 |
|---|---|
| 매일 1회 사망자 정보 수신 | 배치 수신 이력 — 파일 단위 + 레코드 단위 |
| 사망신고 다음 날부터 차단 | 차단개시일시 = 사망일이 아니라 신고일 + 1일 |
| 입금 등 필수 거래만 허용 | 거래유형 × 방향을 데이터로 관리하는 규칙 테이블 |
| 치료비·장례비 예외 인출 | 신청–서류–승인–지급 상태 흐름 + 지정 수취처 |
| 자동이체 중단 | 약정과 처리결과를 분리, 실패사유코드 기록 |
| 처리 이력의 전자적 기록·관리 | 감사로그 — 사망정보 조회 이력까지 포함 |
차단이라는 하나의 흐름을 끝까지 구현하는 데 집중했습니다.
은행 1개사 · 입출금이 자유로운 예금 1종
사망정보 수신 → 고객·계좌 상태 반영 → 거래 차단 판정 → 예외 인출 → 감사·집계
| 카드·보험·증권 | 업권별 원장 구조가 상이 |
| 상속 분할·상속세 | 금융회사 시스템 밖의 업무 |
| 대출 원장 | 차단 대상 유형으로만 존재 |
| 공동망 고정길이 전문 | 참가기관 대상 비공개 규격 |
| 실제 행안부 API | 실습 환경에서 접근 불가 |
제도 문서만 보고 만든 것이 아니라, 근거 법령의 조문을 확인해 다섯 축으로 정리했습니다. 조문을 클릭하면 요지가 열립니다.
| 축 | 근거 법령 | 모델에 반영한 것 |
|---|---|---|
| 기준정보 | 가족관계등록법 제84조·제85조 | death_dt와 death_report_dt를 분리하고, 차단 기준을 신고일+1일로 확정 |
| 개념·논리 | 민법 제998조의2 · 제1000~1003조 | 예외인출 엔터티 도출, 신청인 자격 도메인을 법정 상속순위로 제한 |
| 물리 스키마 | 전자금융거래법 제22조 · 개인정보보호법 제24조의2 | 법정 필수 컬럼 배치, 보존연한 확정, 해시와 암호문 분리 저장 |
| 업무 규칙 | 금융실명법 제3조 · 제4조 | 규칙 테이블 분리, 오매칭 권리구제 이력, 수취처 직수령 금지 |
| 검증·정보계 | 전자금융감독규정 제13조 | 접근 감사로그에 조회 주체·목적·성공여부를 강제 저장 |
실제 은행은 역할에 따라 시스템을 나눕니다. 그 구조를 하나의 MySQL 서버 안에서 데이터베이스(스키마)를 나누는 방식으로 재현했습니다.
행정안전부
한국신용정보원
ext_death_file · ext_death_record · ext_inquiry_log
받은 데이터를 가공하지 않고 보관
cust · acct · acct_txn · death_block · block_rule · exc_* · payee_registry
잔액과 거래를 실제로 움직이는 원장
창구 · ATM
모바일 · 오픈뱅킹
chnl_request · chnl_response · chnl_block_decision
요청을 받아 계정계에 전달하고 결과를 반환
audit_death_access · stat_block_daily · stat_exception_daily · stat_mismatch
영업 종료 후 일배치로 집계. 개인정보 미보관
code_group code_detail rsp_code org_code biz_calendar
— 위 네 계층이 모두 참조합니다. 코드명과 응답 메시지가 여기 한 곳에만 존재합니다.
사망신고부터 집계까지, 각 단계에서 어느 테이블에 행이 생기는지가 곧 그 테이블이 존재하는 이유입니다.
| 일어나는 일 | 행이 생기는 곳 | |
|---|---|---|
| 1 | 새벽 1시, 사망자 파일 수신 | 대외ext_death_file 대외ext_death_record |
| 2 | 해시로 고객 매칭 | 대외ext_death_record match_status_cd 갱신 |
| 3 | 차단 생성 신고일+1일 00:00 산출 |
계정death_block 계정death_block_hist 계정cust_status_hist 계정acct_status_hist |
| 4 | 사망정보를 조회했다는 사실 | 정보audit_death_access |
| 5 | ATM 출금 시도 → 차단 | 채널chnl_request 채널chnl_block_decision 채널chnl_response |
| 일어나는 일 | 행이 생기는 곳 | |
|---|---|---|
| 6 | 타행에서 입금 → 허용 | 계정acct_txn 계정acct balance_amt 갱신 |
| 7 | 자동이체일 도래 → 실패 | 계정auto_transfer_result |
| 8 | 유가족이 장례비 신청 서류 → 2단계 승인 → 이체 |
계정exc_request → 계정exc_document → 계정exc_approval → 계정exc_payout + 계정acct_txn |
| 9 | 오매칭 판명 → 차단 해제 | 계정death_block 갱신 계정death_block_hist 계정cust_status_hist |
| 10 | 영업 종료 후 야간 집계 | 정보stat_block_daily 정보stat_exception_daily 정보stat_mismatch |
계정block_rule 계정payee_registry 공통code_detail 공통rsp_code 공통org_code 공통biz_calendar
출금 요청이 들어오면 세 곳을 읽어 판정하고, 네 곳에 기록합니다.
| 계정ACCT | cust_no 예금주balance_amt 잔액 |
| 계정DEATH_BLOCK | block_status_cd 차단중인가block_start_dtm 지났는가 |
| 계정BLOCK_RULE | allow_yn 이 유형은 허용인가 |
차단이 없으면 규칙은 조회하지 않습니다.
| 채널CHNL_BLOCK_DECISION | 항상 · 허용도 기록 |
| 계정ACCT_TXN | 허용일 때만 기표 |
| 계정ACCT.balance_amt | 허용일 때만 갱신 |
| 정보AUDIT_DEATH_ACCESS | 항상 · 조회 사실 기록 |
원장에는 없지만 판정이력과 감사로그에는 남습니다. 원장과 시도 이력을 분리한 이유입니다.
아래를 클릭하거나 E 키를 누르면 전체 화면 ERD 탐색기가 열립니다. 스키마별로 보거나, FK가 어디서 왔는지 추적할 수 있습니다.
사망신고 기한은 1개월입니다. 사망일로 차단하면 아직 신고되지 않은 사망을 은행이 알 수 없어 제도가 성립하지 않습니다.
| 구분 | 값 |
|---|---|
| 사망일자 | 2026-09-10 |
| 사망 신고일자 | 2026-09-12 |
| 차단개시일시 | 2026-09-13 00:00:00 |
어떤 경로로 데이터가 들어와도 틀린 차단 시각이 저장될 수 없습니다.
-- 애플리케이션이 아니라 DB가 강제한다 CONSTRAINT ck_block_start CHECK ( block_start_dtm = TIMESTAMP(DATE_ADD( death_report_dt, INTERVAL 1 DAY)) )
아래 표는 컬럼 목록이 아니라 block_rule 테이블에 실제로 들어 있는 7개 행입니다. 거래유형 코드를 클릭하면 설명이 열립니다.
| 거래유형 | 방향 | 허용 | 예외인출 | 응답코드 |
|---|---|---|---|---|
| DEP 입금 | 들어옴 | 허용 | — | — |
| TRI 이체입금 | 들어옴 | 허용 | — | — |
| WDR 출금 | 나감 | 차단 | 가능 | D001 |
| TRO 이체출금 | 나감 | 차단 | 가능 | D001 |
| ATO 자동이체 | 나감 | 차단 | 불가 | D002 |
| CLS 계좌해지 | 나감 | 차단 | 불가 | D003 |
| LON 대출실행 | 나감 | 차단 | 불가 | D004 |
txn_type_cd · 방향 dr_cr_cd · 허용 allow_yn · 예외 exception_possible_yn · 응답 reject_rsp_cd이 표는 문서가 아니라 테이블입니다. 규정이 바뀌면 코드를 고치고 재배포하는 대신 UPDATE 한 줄로 끝납니다.
규칙을 수정하지 않고 종료일을 끊고 새 행을 추가합니다. 과거 판정의 근거가 보존됩니다.
코드 자체는 comm_code.rsp_code 한 곳에만 있고, 쓰는 쪽은 코드 값만 갖고 FK로 참조합니다. 참조하는 컬럼이 7개입니다.
CHECK 제약 하나로 "허용인데 거절코드가 있는" 모순된 규칙이 저장되지 않습니다.
상태와 테이블 이름을 클릭하면 각 단계의 의미와 테이블 속성을 볼 수 있습니다.
| 테이블 | 역할 |
|---|---|
| 계정EXC_REQUEST | 신청 1건의 전체 상태 |
| 계정EXC_DOCUMENT | 증빙서류 N건과 검증결과 |
| 계정EXC_APPROVAL | 차수별 승인 이력 |
| 계정EXC_PAYOUT | 실제 지급 1건 |
| 계정PAYEE_REGISTRY | 사전 등록된 병원·장례식장 |
승인되어도 병원·장례식장 계좌로 직접 이체됩니다. 본인 현금 인출이 아닙니다.
이 원칙을 애플리케이션 코드가 아니라 스키마로 강제한 것이 다음 장입니다.
지켜야 할 정책은 하나입니다. 예외인출 대금은 등록된 병원·장례식장으로만 나간다. 이걸 어디서 막느냐가 문제입니다.
if (!payeeRepo.exists(payeeId)) { throw new Exception("미등록 수취처"); }
문제는 이 코드를 거치지 않는 경로가 존재한다는 것입니다.
| 창구 애플리케이션 | 검증 코드 있음 |
| 야간 배치 프로그램 | 다른 팀이 만듦 |
| 운영자의 DB 콘솔 | 코드를 안 거침 |
| 데이터 이관 스크립트 | 일회성이라 검증 생략 |
코드로 막으면 첫 번째 경로만 지켜집니다.
payee_id BIGINT NOT NULL, CONSTRAINT fk_expay_payee FOREIGN KEY (payee_id) REFERENCES payee_registry (payee_id)
NOT NULL — 비워 둘 수 없다
FOREIGN KEY — 등록된 수취처가 아니면 값이 될 수 없다
두 제약이 함께 있어야 합니다. NULL은 FK 검사를 통과하기 때문입니다.
어느 경로로 들어오든 DB 엔진이 트랜잭션을 거절합니다. 상속인 개인계좌 번호가 들어갈 자리 자체가 스키마에 없습니다.
ERROR 1452: a foreign key constraint fails
(`exc_payout`, CONSTRAINT `fk_expay_payee`)
전체 68개 FOREIGN KEY 중, 아래 8개 컬럼만 의도적으로 FK 없이 두었습니다.
| 관계 | FK를 걸지 않은 이유 |
|---|---|
| EXT_DEATH_RECORD → CUST | 대외계 원천을 재적재·정리할 때 계정계가 막히면 안 됨 |
| EXT_DEATH_RECORD → DEATH_BLOCK | 동일 |
| CHNL_REQUEST.acct_no | 존재하지 않는 계좌번호로 들어온 요청도 기록되어야 함 — FK를 걸면 공격 시도를 추적할 수 없음 |
| AUDIT_DEATH_ACCESS.target_cust_no | 감사로그는 대상이 사라져도 남아야 함 |
| CHNL_BLOCK_DECISION.applied_rule_id | 규칙이 폐기돼도 과거 판정 이력은 보존되어야 함 |
| BLOCK_RULE → ACCT_TXN | 판정 시점의 참조. 규칙 폐기 후에도 과거 거래는 존재 |
고객 상태가 바뀔 때마다 기존 행을 남기고 새 행을 추가하는 SCD Type 2 방식을 썼습니다.
valid_to_dtm DATETIME(3) NOT NULL DEFAULT '9999-12-31 23:59:59.999', UNIQUE KEY uk_cust_hist_current (cust_no, valid_to_dtm)
현재 유효한 행은 종료일시를 센티널 값으로 채웁니다.
MySQL의 UNIQUE는 NULL을 서로 다른 값으로 취급해 중복을 허용합니다. NULL이면 "현재 행"이 여러 개여도 막히지 않습니다.
고객당 현재 행이 정확히 1건임을 DB가 보장합니다. 배치가 두 번 돌아도 안전합니다.
다만 close_dt처럼 "구간의 끝"이 아니라 "사건의 발생 여부"를 뜻하는 컬럼은 NULL이 맞습니다. 센티널을 넣으면 평균 존속기간 같은 집계가 왜곡됩니다.
30개 테이블 전부 제3정규형을 만족합니다. 단계별로 무엇을 제거했는지 점검했습니다.
| 단계 | 제거 대상 | 우리 모델에서 실제로 한 일 |
|---|---|---|
| 1NF | 다중값 · 반복 속성 | 증빙서류를 EXC_DOCUMENT로, 승인을 EXC_APPROVAL로 분리해 한 건당 한 행으로 |
| 2NF | 부분 함수 종속 | 복합키는 CODE_DETAIL(group_cd, code_cd) 하나뿐이며, code_nm은 두 컬럼이 모두 있어야 결정됨 |
| 3NF | 이행 함수 종속 | 기관명·코드명·응답메시지를 원장에 두지 않고 코드만 저장해 조인. 코드 테이블 5종이 이 역할 |
| BCNF | 후보키가 아닌 결정자 | 점검 결과 별도 분해가 필요한 사례는 확인되지 않음 |
30개 중 12개가 정규화 과정에서 분리된 것입니다. 이력 3종, 예외인출 4종, 코드 5종.
3개 컬럼만 의도적 반정규화로 예외 처리했습니다. 근거와 대가는 다음 장에서.
규제 요건을 문서로만 정리하지 않고 실제 스키마에 반영했습니다.
| 법령 요건 | 반영 | 이유 |
|---|---|---|
| 개인정보보호법 제24조의2 |
rrn_hash CHAR(64)rrn_enc VARBINARY(128) |
검색용 해시와 저장용 암호문을 분리. 해시는 되돌릴 수 없어 매칭만 가능 |
| 전자금융거래법 제22조 |
terminal_id 추가 |
거래 추적·오류 정정에 필요한 법정 기록 항목 |
| 신용정보법 제20조의2 |
cust.close_dt |
상거래관계 종료일. 보존기간 5년의 기산점 |
보존연한 관리에는 유리하지만, MySQL InnoDB는 파티션 테이블에 FK를 걸 수 없습니다. 실제로 시도하면 ERROR 1506이 납니다. 67개 FK로 얻은 참조 무결성을 포기할 수 없어 아카이브 테이블 이관 방식으로 대체했습니다.
이유는 두 가지뿐입니다. 조회 성능과 판정 시점의 값 고정.
| 컬럼 | 이유 | 왜 중복을 허용했나 | 지불한 대가 |
|---|---|---|---|
| ACCT .balance_amt | 성능 | 거래원장 합계로 구할 수 있지만, 20년치가 쌓이면 잔액 조회 한 번에 수만 행을 훑어야 함 | 잔액–원장 대사 쿼리가 필요해짐 |
| ACCT_TXN .balance_after_amt | 시점 | 그 거래 직후의 잔액을 재계산 없이 답하기 위해. 오픈뱅킹 거래내역조회 API 응답 필드와도 일치 | 원장 수정 시 재계산 필요 |
| DEATH_BLOCK .death_report_dt | 시점 | 원천이 정정·재전송돼도 판정에 실제로 쓴 값은 바뀌면 안 됨 | 원천과 불일치 가능 → 정합성 점검 |
보안이나 교차검증이 목적이 아닙니다. 중복을 만들었기 때문에 어긋날 위험이 생겼고, 그래서 대사 쿼리가 필요해진 것입니다.
판단 기준 3가지 — ① 조회가 쓰기보다 훨씬 잦은가 ② 재계산 비용이 데이터 증가에 비례하는가 ③ 어긋남을 검증할 방법이 있는가. 셋을 모두 만족할 때만 허용했습니다.
payee_id가 EXC_REQUEST와 EXC_PAYOUT 양쪽에 있는 것은 의미가 다른 별개 컬럼입니다. 신청 시 지정한 곳과 실제 지급한 곳. 이건 교차검증이 목적이 맞습니다.
차단개시일시를 사이에 두고 동일한 출금 요청이 정반대로 처리됩니다.
| 요청일시 | 시점 | 판정 | 응답 | 메시지 |
|---|---|---|---|---|
| 2026-09-12 23:59:00 | 차단개시 전 | 허용 | 0000 | 정상 처리되었습니다 |
| 2026-09-13 00:00:01 | 차단개시 후 | 차단 | D001 | 사망자 명의 계좌로 출금 거래가 제한됩니다 |
규칙 테이블을 조인한 판정 시뮬레이션 — IF문 없이 SQL만으로 판정합니다.
| 고객 | 거래유형 | 거래일시 | 판정 |
|---|---|---|---|
| C0000000002 | DEP 입금 | 09-14 10:00 | 허용 — 규칙상 필수거래 |
| C0000000002 | ATO 자동이체 | 09-15 03:00 | 차단 — D002 |
| C0000000002 | CLS 계좌해지 | 09-15 09:30 | 차단 — D003 |
미등록 수취처, 즉 상속인 개인계좌로 예외인출을 지급하려고 시도했습니다.
INSERT INTO exc_payout (exc_request_id, payee_id, ...) VALUES (1, 9999, ...); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`core_bank`.`exc_payout`, CONSTRAINT `fk_expay_payee` FOREIGN KEY (`payee_id`) REFERENCES `payee_registry` (`payee_id`))
FK 위반 — 부모 테이블에 없는 값
UNIQUE 위반 — 중복된 값
CHECK 위반 — 조건 불충족
총 12개 위반 시나리오를 검증했습니다. 차단 기준일 오류, 이중 지급, 이력 현재행 2건 등이 모두 DB 단계에서 거부됩니다.
설계한 규칙이 데이터에서 실제로 지켜지는지 네 가지를 쿼리로 확인했습니다.
| 검증 | 확인하는 것 | 결과 |
|---|---|---|
| 잔액 = 원장 합계 | 반정규화한 balance_amt가 거래원장 입출금 합계와 같은가 |
5개 계좌 전부 일치 |
| 이력 현재행 | 고객마다 "지금 유효한 상태" 행이 정확히 1건인가 2건이면 현재 상태 조회에 답이 두 개가 됨 |
5명 전부 1건 |
| 유효구간 연속성 | 앞 행의 종료와 뒤 행의 시작이 정확히 맞물리는가 틈이 있으면 그 시점 상태를 알 수 없고, 겹치면 상태가 두 개 |
단절·중복 없음 |
"임의의 시점 T에 이 고객이 차단 상태였는가"에 답이 정확히 하나 나와야 차단의 정당성을 증명할 수 있습니다.
김정상(생존) · 박순자(차단, 예외인출 2건) · 이영희 ×2(동명이인) · 최말순(오차단 후 해제)
행안부 제공 정보에 사망신고일자가 포함된다고 가정했습니다. 실제 규격을 확인할 수 없었고, 이 가정이 틀리면 제도 자체가 성립하지 않습니다.
해시 기반 매칭은 동명이인을 구분하지만, 원천에 주민번호가 없으면 성명·생년월일로 다건매칭이 발생합니다. 자동 차단하지 않고 수작업 확인 대상으로 분리했습니다.
① 배치 프로시저 — 사망정보 매칭에서 차단 생성까지
② 판정 로직을 Java 서비스 계층으로 이관
③ 로그 보존기간 확정 (전자금융거래법 제22조)
판정 로직을 프로시저에 두껍게 넣지 않았습니다. 규칙은 테이블에, 조합과 분기는 서비스 계층에 두는 구조입니다.
이서현, 이채원
배경 · 범위 · 아키텍처 · 차단 기준일 · 규칙 설계 · 예외인출 · 무결성 · 시연
| 위반했다면 이런 모습 | 우리 모델 | 제거한 종속 |
|---|---|---|
exc_request.documents= '가족관계증명서, 영수증' |
EXC_DOCUMENT 분리 |
1NF · 한 칸에 여러 값. 서류별 검증결과를 기록할 수 없음 |
exc_request.approver1_idexc_request.approver2_id |
EXC_APPROVAL 분리 |
1NF · 반복 속성. 3차 승인이 생기면 구조 변경 필요 |
acct_txn.counter_org_nm(상대 기관명) |
ORG_CODE 조인 |
3NF · 기관명은 거래가 아니라 기관코드가 결정 |
acct_txn.rsp_message(응답 메시지) |
RSP_CODE 조인 |
3NF · 메시지는 응답코드가 결정 |
cust.cust_status_nm('사망') |
CODE_DETAIL 조인 |
3NF · 상태명은 상태코드가 결정 |
cust.cust_status_cd를UPDATE로 덮어씀 |
CUST_STATUS_HIST |
정규화는 아니지만 시점 정보 손실 방지 |
각 테이블의 비주키 속성이 기본키 전체에만 종속되는지 확인했습니다. 코드명·기관명처럼 다른 속성이 결정하는 값은 전부 참조 테이블로 뺐습니다.
| 용도 | 선택 | 이유 |
|---|---|---|
| 금액 | DECIMAL(18,2) | FLOAT/DOUBLE은 이진 부동소수점이라 십진 소수를 정확히 표현하지 못해 잔액 대사가 어긋남 |
| 일시 | DATETIME(3) | TIMESTAMP는 2038년 한계가 있고 세션 타임존에 따라 값이 변환됨 |
| 계좌·고객번호 | VARCHAR | 앞자리 0을 보존해야 하고 산술 연산을 하지 않음 |
| Y/N 여부 | CHAR(1) | TINYINT(1)은 드라이버 설정에 따라 Boolean/Integer로 달라짐 |
| 코드값 | CHAR(4) + 코드표 | ENUM은 값을 추가할 때마다 ALTER TABLE이 필요 |
| 해시 | CHAR(64) | SHA-256 hex 고정 64자. 주민번호 평문을 저장하지 않음 |
| 대리키 | BIGINT | UNSIGNED는 JDBC에서 BigInteger로 매핑되어 다루기 번거로움 |
코드표 CODE_DETAIL의 기본키는 (group_cd, code_cd) 두 컬럼입니다. 10이라는 코드값이 고객상태 그룹에도, 예외인출사유 그룹에도 있어서 코드값만으로는 유일하지 않기 때문입니다.
그런데 CUST 테이블에는 cust_status_cd만 있고 group_cd가 없습니다. 외래키는 부모의 기본키 전체를 가리켜야 하므로 걸 수가 없습니다.
① 코드 그룹마다 테이블을 따로 만든다 → 테이블이 24개 늘어남
② CHECK로만 검증한다 → 코드가 추가될 때마다 제약을 고쳐야 함
cust_status_cd CHAR(4), cust_status_grp CHAR(10) GENERATED ALWAYS AS ('CUST_ST') STORED, FOREIGN KEY (cust_status_grp, cust_status_cd) REFERENCES code_detail (group_cd, code_cd)
cust_status_grp는 항상 'CUST_ST'가 되는 컬럼입니다. MySQL이 자동으로 채우므로 INSERT에 쓰지 않습니다. 이 컬럼 덕분에 두 컬럼짜리 외래키가 성립합니다.
고객상태 컬럼에 예외인출 상태값 REQ를 넣으면 거부됩니다. 존재하는 코드인지뿐 아니라 이 컬럼에 맞는 그룹의 코드인지까지 막습니다.
비용 — 생성컬럼 35개 추가, FK마다 인덱스 자동 생성, CASCADE 사용 불가
책 뒤의 찾아보기와 같습니다. 원하는 내용을 처음부터 넘겨보지 않고 바로 찾아가게 해 줍니다.
거래 100만 건에서 특정 계좌의 거래를 찾으려면 100만 건을 전부 읽어야 합니다. 이걸 풀 스캔이라고 합니다.
정렬된 색인을 따라가 수십 번의 비교로 찾습니다.
저장 공간을 더 쓰고, INSERT할 때마다 색인도 갱신해야 해서 쓰기가 느려집니다. 그래서 자주 쓰는 조회에만 만듭니다.
PK · UNIQUE · FK 컬럼은 MySQL이 자동으로 인덱스를 만들어 줍니다. 아래는 그 외에 직접 추가한 것입니다.
| 인덱스 | 이 조회를 위해 |
|---|---|
| ACCT_TXN (acct_no, txn_dtm) | 계좌별 기간 거래내역 — 가장 빈번 |
| DEATH_BLOCK (block_start_dtm) | 일별 신규 차단 집계 |
| CUST_STATUS_HIST (cust_no, valid_from_dtm) | 특정 시점의 고객 상태 조회 |
| EXT_DEATH_RECORD (rrn_hash) | 일배치 사망자 매칭 |
(acct_no, txn_dtm)은 "계좌로 먼저 좁히고 그 안에서 기간으로 좁힌다"는 뜻입니다. 순서를 바꾸면 계좌별 조회에는 잘 듣지 않습니다.
실습 데이터가 소량이라 EXPLAIN 측정은 유의미하지 않아 설계 근거만 제시합니다.
| 조문 | 핵심 내용 | 모델 반영 |
|---|---|---|
| 가족관계등록법 제84조 | 사망 사실을 안 날부터 1개월 이내 신고 | 사망일과 신고일이 최대 1개월 벌어짐 → 컬럼 분리 |
| 가족관계등록법 제85조 | 동거하는 친족이 신고의무자 | 신고 주체와 예외인출 신청인이 다를 수 있음을 전제 |
| 민법 제997조 | 상속은 사망으로 개시 | 사망 시점부터 계좌 자산은 상속재산 → 동결 원칙 |
| 민법 제998조의2 | 상속비용은 상속재산 중에서 지급 | 예외인출 제도의 법적 근거. exc_reason_cd 도메인 |
| 민법 제1000~1003조 | 직계비속 → 직계존속 → 형제자매, 배우자는 공동상속 | applicant_rel_cd를 법정 순위로 제한 |
| 조문 | 핵심 내용 | 모델 반영 |
|---|---|---|
| 전자금융거래법 제22조 | 거래기록 생성·보존 의무 | 일시·금액·방향·채널·단말·상대방 컬럼 배치 |
| 시행령 제12조 | 1만원 초과 5년, 이하 1년 | 보존정책 확정. 아카이브 이관 기준 |
| 개인정보보호법 제24조의2 | 주민번호 암호화 보관 의무 | rrn_hash(검색) + rrn_enc(저장) 분리 |
| 신용정보법 제20조의2 | 상거래 종료 후 최장 5년 내 삭제·분리 | close_dt로 기산점 확보 |
| 금융실명법 제3조 | 실명거래 의무, 실명계좌 자산은 명의자 소유로 추정 | 오매칭 시 권리구제 → 해제 + SCD 이력 |
| 금융실명법 제4조 | 명의인 동의 없는 제3자 제공 금지 | 상속인 직수령 차단 → payee_registry FK |
금융 도메인 데이터 모델이 일반적으로 갖춰야 할 항목과 본 모델의 충족 현황입니다.
| 점검 항목 | 본 모델 |
|---|---|
| 모든 테이블에 감사 컬럼(등록·수정 일시와 사용자)이 있는가 | 충족 |
| 거래내역이 UPDATE·DELETE 없이 INSERT만 되는 구조인가 | 충족 |
고유식별정보가 _hash / _enc로 구분되어 있는가 | 충족 |
| 고객·계좌에 거래종료일이 있어 보존기간을 계산할 수 있는가 | 충족 |
| 거래내역에 채널·단말·현금여부·상대방 정보가 있는가 | 충족 |
| 마스터 변경 시 이력 테이블이 있는가 | 충족 |
| 직원 권한과 고객정보 접근로그 구조가 있는가 | 충족 |
| 코드성 값이 ENUM이 아닌 공통코드 테이블로 관리되는가 | 충족 |
| 실명확인·고객확인(CDD) 정보가 기본정보와 분리된 이력 구조인가 | 범위 외 |
잘못 차단하면 생존 고객의 금융거래가 막힙니다. 다건매칭은 match_status_cd = '40'으로 분리해 담당자가 확인합니다.
DEATH_BLOCK의 상태를 해제로 바꾸고 DEATH_BLOCK_HIST에 사유와 조치자를 남깁니다.
샘플 데이터의 최말순이 이 경로를 밟습니다. 09-13 차단 → 09-15 해제 → 이후 정상 출금.