-
[4] 데이터베이스 논리적 모델링1 - 테이블 설계프로젝트/대출금 상환 프로젝트 2026. 6. 3. 16:55
이전 글에서 대출 도메인의 비즈니스 요구사항을 바탕으로 개념적 모델링을 완성했습니다.
이번 글은 논리적 모델링 1편으로, 개념적 모델의 엔티티를 관계형 데이터베이스의 테이블로 변환하는 과정을 다룹니다.
논리적 모델링 2편에서는 설계한 테이블의 품질을 높이는 정규화(Normalization)를 다룰 예정입니다.
이번 설계에서 적용할 원칙은 다음과 같습니다.
- 대리키 PK, 자연키 UNIQUE: 비즈니스와 무관한 대리키를 PK로 사용하고, 비즈니스적으로 유일한 값에는 UNIQUE 제약조건을 적용합니다.
- 비식별 관계: 유연성과 확장성을 위해 FK를 PK의 일부로 사용하지 않는 비식별 관계를 선택합니다.
- 1:1 관계의 FK 위치: 보조 테이블에 FK를 두고, 해당 FK에 UNIQUE 제약조건을 추가하여 1:1 관계를 강제합니다.
- NULL 제약조건으로 참여도 제어: FK의 NOT NULL 여부로 필수/선택 참여를 표현합니다.
설계할 테이블 목록은 다음과 같습니다.
- 코드성 테이블: 이자종류, 상환방법, 대출상태
- 핵심 테이블: 회원, 주 계좌, 대출상품
- 운영 테이블: 대출계약, 대출계좌, 대출상태 이력
- 상환 테이블: 상환 스케줄, 상환 이력, 연체 이력
1: 이자종류 , 상환방법 , 대출상품
1. 이자종류 테이블
: 대출에 적용되는 이자 유형을 관리하는 코드성 테이블입니다.
기본키(PK): 종류id

설계노트
이자종류명은 비지니스적으로 유일해야 하는 자연키 후보 입니다.
대리키 원칙에 따라 PK 는 시스템이 생성하는 종류id 로 두고, 이자종류명에는 UNIQUE 제약조건을 적용합니다.
덕분에 이자종류명이 변경되더라도 이를 참조하는 대출상품 테이블의 FK 는 아무런 영향을 받지 않습니다.
2. 상환방법 테이블
: 대출 상환 방식을 관리하는 코드성 테이블입니다.
기본키(PK): 방법id

설계노트
이자종류 테이블과 동일한 패턴을 적용합니다.
같은 상품명이더라도 이자종류나 상환방법이 다르면 다른 상품으로 분류하기에 , 독립 테이블로 분리하여 대출상품에서 FK 로 참조하는 방식을 선택했습니다.
3. 대출상품 테이블
: 대출 서비스에서 제공하는 상품 정보를 저장하는 테이블입니다.
기본키(PK): 상품id
외래키(FK): 이자종류id , 상환방법id

설계노트
상품명에 UNIQUE 제약조건을 걸지 않았습니다.
설계 상 , 같은 상품명이더라도 이자종류나 상환방법이 다른 상품이 각각 존재할 수 있기 때문입니다.
개념적 모델링 -> 논리적 모델링

개념적 모델링 
논리적 모델링 - 테이블 설계
2: 회원 , 주 계좌
1. 회원 테이블
: 대출 서비스를 이용하는 회원 정보를 저장하는 테이블입니다.
기본키(PK): 회원id

설계노트
대리키 원칙에 따라 PK 는 회원 id 로 두고 , 로그인 id 에는 UNIQUE 제약조건을 적용합니다.
덕분에 회원이 로그인 id 를 변경하더라도 이를 참조하는 대출계약 데이터는 아무런 영향을 받지 않습니다.
2. 주 계좌 테이블
: 회원의 주 계좌 정보를 저장하는 테이블입니다.
기본키(PK): 계좌id
외래키(FK): 회원id

설계노트
회원과 주 계좌는 1:1 관계 입니다.
회원이 먼저 존재해야 주 계좌가 생성되는 흐름이므로, 회원이 주 테이블이고 주 계좌가 보조 테이블 입니다.
보조 테이블에 FK 를 두는 원칙에 따라 주 계좌 테이블에 회원 id KF 를 배치했습니다.
회원 id 에 UNIQUE 제약조건을 추가하여 한 회원이 두 개 이상의 주 계좌를 갖는 상황을 DB 레벨에서 방지 합니다.
개념적 모델링 -> 논리적 모델링

개념적 모델링 
논리적 모델링 - 테이블 설계
3: 대출계약 , 대출계좌
1. 대출계약 테이블
: 회원이 특정 대출상품에 가입할 때 생성되는 계약 정보를 저장하는 테이블입니다.
기본키(PK): 계약id
외래키(FK): 회원id,상품id

설계노트
회원과 대출상품의 M:N 관계를 해소하기 위한 연결 테이블 입니다.
하나의 회원은 여러 대출 상품에 가입할 수 있고 , 하나의 대출 상품은 여러 회원에게 적용될 수 있습니다.
대출계약에서 회원id , 상품id 에 UNIQUE 제약조건을 걸지 않았습니다.
동일한 회원이 같은 대출상품으로 여러 번 계약할 수 있는 비지니스 상황이 존재하기 때문입니다.
예를 들어 기존 대출을 상환한 후 동일 상품으로 재대출하는 경우가 이에 해당합니다.
계약대출원금은 계약시점의 대출 원금을 저장합니다.
상환이 진행되어도 계약 당시 원금은 변하지 않아야 합니다.
2. 대출계좌 테이블
: 대출계약이 실행된 이후 실제 대출 운영 정보를 저장하는 테이블입니다.
기본키(PK): 계좌id
외래키(FK): 계약id,주계좌id

설계노트
대출계약과 대출계좌는 1:1 관계 입니다.
대출계약이 먼저 존재해야 대출계좌가 생성되는 흐름이므로 , 대출계약이 주 테이블이고 대출계좌가 보조 테이블 입니다.
보조 테이블에 FK 를 두는 원칙에 따라 대출계좌 테이블에 계약id FK 를 배치했습니다.
계약id 에 UNIQUE 제약조건을 추가하여 하나의 계약에 2개 이상의 대출계좌가 생성되는 상황을 DB 레벨에서 방지 합니다.
ERD 의 상환계좌번호 컬럼은 설계 과정에서 주계좌id FK 로 대체 했습니다.
계좌번호 문자열을 직접 저장하면 계좌번호가 변경될 경우 수동으로 업데이트 해야 하고 , DB 가 데이터 정합성을 보장할 수 없습니다.
반면 주계좌id 를 FK 로 참조하면 FK 제약조건으로 정합성이 자동으로 보장됩니다.
개념적 모델링 -> 논리적 모델링

개념적 모델링 
논리적 모델링 - 테이블 설계
3: 대출상태 , 대출상태이력
1. 대출상태 테이블
: 대출계좌의 상태 유형을 관리하는 코드성 테이블입니다.
기본키(PK): 상태id

설계노트
대출계좌의 상태 유형을 관리하는 코드성 테이블 입니다.
이자종류 , 상환방법 테이블과 동일한 패턴을 적용합니다.
상태명은 비지니스적으로 유일해야 하는 자연키 후보이므로 UNIQUE 제약조건을 적용합니다.
덕분에 상태명이 변경되더라도 이를 참조하는 대출상태 이력 테이블의 FK 는 아무런 영향을 받지 않습니다.
2. 대출상태 이력 테이블
: 대출계좌의 상태 변화 이력을 저장하는 테이블입니다. 대출계좌의 상태가 변경될 때마다 새로운 row가 추가됩니다.
기본키(PK): 이력id
외래키(FK): 대출계좌id , 상태id

설계노트
종료일에 NULL 을 허용합니다.
현재 진행 중인 상태는 아직 종료되지 않았으므로 종료일이 없습니다.
즉 , 종료일 = NULL 은 현재 활성 상태임을 의미 합니다.
이 패턴을 활용하면 "WHERE 종료일 IS NULL" 조건으로 현재 활성 상태를 간단하게 조회할 수 있습니다.
개념적 모델링 -> 논리적 모델링

개념적 모델링 
논리적 모델링 - 테이블 설계
4: 상환 스케줄 , 상환 상태 , 상환 이력 , 연체 이력
1. 상환상태 테이블
: 상환 스케줄의 상태 유형을 관리하는 코드성 테이블입니다.
기본키(PK): 상태id

설계노트
이자종류,상환방법,대출상태 테이블과 동일한 패턴을 적용합니다.
현재는 MVP 개발 단계이지만 , 서비스가 확장되면서 새로운 상태가 추가될 수 있습니다.
또한 상태명이 변경될 경우, VARCHAR 컬럼으로 관리하면 해당 값이 저장된 모든 row 를 수정해야 합니다.
코드성 테이블로 분리하면 상태 테이블의 row 하나만 수정하면 되므로 확장성과 유지보수성을 위해 독립 테이블로 분리했습니다.
2. 상환 스케줄 테이블
: 대출계좌의 회차별 상환 예정 정보를 저장하는 테이블입니다. 대출 실행 시점에 전체 상환 일정이 생성됩니다.
기본키(PK): 스케줄id
외래키(FK): 대출계좌id , 상태id

설계노트
대출 계좌의 회차별 상환 예정 정보를 저장하는 테이블 입니다.
적용금리는 상환 스케줄 생성 시점의 금리를 스냅샷으로 저장합니다.
변동금리 상품의 경우 금리가 변경될 수 있으므로 , 각 회차별 실제 적용된 금리를 별도로 저장해야 과거 이력을 정확하게 추적할 수 있습니다.
3. 연체 종류 테이블
: 연체 이력의 연체 유형을 관리하는 코드성 테이블입니다.
기본키(PK) : 종류id

설계노트
이자종류, 상환방법, 대출상태, 상환상태 테이블과 동일한 패턴을 적용합니다.
연체 이력은 연체가 발생할 때마다 매일 row가 추가되는 테이블입니다.
VARCHAR 컬럼으로 관리하면 오타나 잘못된 값이 저장될 위험이 있고, DB 레벨에서 유효한 값인지 검증할 수 없습니다.
4. 연체 이력 테이블
: 연체가 발생한 상환 스케줄의 연체 정보를 저장하는 테이블입니다. 연체가 발생할 때마다 새로운 row가 추가됩니다.
기본키(PK): 연체id
외래키(FK): 스케줄id , 연체종류id

설계노트
상환 스케줄과 연체 이력은 1:N 관계로, 하나의 스케줄에서 연체가 여러 번 발생할 수 있습니다.
예를 들어 1회차 스케줄에서 연체가 발생했다가 일부 해소되고, 이후 다시 연체가 발생하는 경우가 이에 해당합니다.
연체이자율은 연체 발생 시점의 이자율을 스냅샷으로 저장합니다. 이자율은 시간이 지남에 따라 변경될 수 있으므로, 연체가 발생한 시점의 이자율을 별도로 저장해야 과거 연체 이력을 정확하게 추적할 수 있습니다.
스케줄id는 NOT NULL로 설정합니다. 연체는 반드시 특정 회차의 상환 스케줄에서 발생하며, 스케줄 없는 연체 이력은 비즈니스적으로 존재할 수 없기 때문입니다. 또한 연체 이력이 스케줄id를 FK로 보유하고 있기 때문에, 상환 이력에서 연체id를 선택적으로 참조하는 것만으로도 해당 연체의 스케줄 정보를 추적할 수 있습니다.
4. 상환 이력 테이블
: 실제 납부가 완료된 상환 내역을 저장하는 테이블입니다. 납부가 발생할 때마다 새로운 row가 추가됩니다.
기본키(PK): 이력id
외래키(FK): 스케줄id,연체id

설계노트
상환 스케줄과 상환 이력은 1:N 관계입니다.
하나의 스케줄에 여러 번의 납부 이력이 생길 수 있기 때문입니다. 예를 들어 부분 납부가 여러 차례 발생하는 경우가 이에 해당합니다.
스케줄id는 NOT NULL로 설정합니다.
모든 납부는 반드시 특정 회차의 스케줄에 대한 납부이며, 스케줄 없는 납부 이력은 비즈니스적으로 존재할 수 없기 때문입니다.
연체id는 NULL을 허용합니다.
정상 납부의 경우 연체 이력이 존재하지 않으므로 선택적으로 연결됩니다.
연체가 발생한 납부의 경우에만 연체 이력 테이블의 연체id를 참조합니다.
이 설계를 통해 "연체id IS NULL" 조건으로 정상 납부 이력을, "연체id IS NOT NULL" 조건으로 연체 납부 이력을 간단하게 구분할 수 있습니다.
납부연체금은 정상 납부의 경우 0으로 저장됩니다.
개념적 모델링 -> 논리적 모델링

개념적 모델링 
논리적 모델링 - 테이블 설계
논리적 모델링 - 테이블 설계 결과

지금까지 대출 도메인의 개념적 모델을 바탕으로 논리적 모델링 1편, 테이블 설계를 완성했습니다.
최종적으로 설계한 테이블 목록은 다음과 같습니다.
- 코드성 테이블: 이자종류, 상환방법, 대출상태, 상환상태, 연체상태
- 핵심 테이블: 회원, 주 계좌, 대출상품
- 운영 테이블: 대출계약, 대출계좌, 대출상태 이력
- 상환 테이블: 상환 스케줄, 상환 이력, 연체 이력
다음 글에서는 이 논리적 모델의 품질을 한 단계 더 끌어올려 데이터 중복을 최소화하고 무결성을 극대화하는 과정인 정규화를 진행하겠습니다.
'프로젝트 > 대출금 상환 프로젝트' 카테고리의 다른 글
은행 아키텍처 알아보기 (0) 2026.06.21 [6] 데이터베이스 물리적 모델링 (0) 2026.06.14 [5] 데이터베이스 논리적 모델링2 - 정규화 (0) 2026.06.06 [3] 데이터베이스 개념적 모델링 (0) 2026.05.31 [2] 가계 대출 상품 설명서 분석 - 2 (0) 2026.05.17 [2] 가계 대출 상품 설명서 분석 - MVP 기능 (0) 2026.05.17 [4] 대출금 상환 프로그램 설계 (0) 2026.05.04 [1] 프로젝트 개요 (0) 2026.05.02