284. 버저닝 데이터 모델

핵심 인사이트 (3줄 요약)

  1. 본질: 버저닝 데이터 모델(Versioning Data Model)은 데이터의 변경 이력(History)을 명시적으로管理하는 설계 기법으로, 시간에 따른 데이터 상태 추적과 감사(Audit) 추적이 필요한 시스템에 필수적이다.
  2. 가치: 과거 데이터 조회, 변경 취소(Undo), 감사 로그, 법規制 준수(Compliance), SCD(Slowly Changing Dimension) 처리가 가능하다.
  3. 융합: CDC, 트랜잭션 로그, SCD 타입별 처리, Temporal Database, 메타데이터 管理와 밀접하게 연관된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

개념 정의

버저닝 데이터 모델(Versioning Data Model)은 데이터의 변경 이력을 명시적으로 저장하고管理하는 데이터 모델링 기법이다. 단순히 최신 데이터만 저장하는 것이 아니라, 데이터가 생성된 시점, 수정된 시점, 삭제된 시점을 모두 기록한다. 이를 통해 시간 여행(Time Travel)처럼 과거任意 시점의 데이터를 조회하거나, 변경 이력을 추적할 수 있다.

필요성

비즈니스 시스템에서는 데이터 변경에 대한 감사(Audit) 추적이 필수적인 경우가 많다. 금융 거래, 의료 기록, 개인정보 등 regulatory compliance가 요구되는 데이터는 변경 이력을 반드시保存해야 한다. 또한 사용자가 실수로 데이터를 잘못 수정했을 때 이전 상태로 복구하는 기능도 필요하다. 일반적인 UPDATE 연산은 이전 값을 덮어쓰워 복구가 불가능하지만, 버저닝을 적용하면 언제든지 이전 상태를 조회할 수 있다.

배경

관계형 데이터베이스에서 버저닝은 전통적으로 별도의 이력 테이블을 만들어管理했다. 그러나 NoSQL에서는 유연한 스키마를 활용하여 자체적으로 버저닝을 지원하는 구조도 있다. 또한 Slowly Changing Dimension(SCD) 처리에서 파생된 Type 1, 2, 3 등의 버저닝 전략이 데이터웨어하우스에서 널리 사용된다. 최근에는 CDC(Change Data Capture)와 결합하여 실시간 데이터 변경 추적에도 활용된다.

비유

버저닝 데이터 모델은大型도서관의 책 loans نظام과 같다. 책 자체를 빌리거나 반납할 때borrower, date Borrowed, date Returned를 기록한다. 현재 누가 빌리고 있는지도 중요하지만, 과거에 누가 빌렸었는지도 기록한다. 이렇게 하면 특정 책의 대출 이력을 언제든지 추적할 수 있다.

📢 섹션 요약: 버저닝 데이터 모델은 데이터의 시간에 따른 변경 이력을 명시적으로 저장하여, 과거 데이터 조회, 감사 추적, 변경 복구가 가능한 데이터 모델링 기법이다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

버저닝 구현 방식

┌─────────────────────────────────────────────────────────────────────────────┐
│                    버저닝 데이터 모델 구현 방식                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [방식 1] 이중 테이블 방식 (Two-Table Approach)                             │
│  ─────────────────────────────────────────────                              │
│  • 현재 테이블 (Current Table): 최신 데이터만 저장                            │
│  • 이력 테이블 (History Table): 변경된 모든 데이터를 時系列로 저장            │
│                                                                             │
│  ┌─────────────────────┐         ┌─────────────────────┐                 │
│  │  customers (현재)   │         │  customers_history  │                 │
│  │─────────────────────│         │─────────────────────│                 │
│  │ id | name | status  │         │ id | name | status  │                 │
│  │ 1  | 김철수 | 활성   │         │ 1  | 김철수 | 활성   │2024-01-01 10:00│
│  │                     │  UPDATE │ 1  | 김철수 | 휴면   │2024-03-15 14:30│
│  └─────────────────────┘────────▶└─────────────────────┘                 │
│                                                                             │
│  [방식 2] 단일 테이블에 버전 컬럼 추가                                        │
│  ──────────────────────────────────────────                                 │
│  • start_date, end_date, is_current 등의 컬럼으로 버전 관리                  │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │                    customers (단일 테이블)                           │      │
│  │──────────────────────────────────────────────────────────────────│      │
│  │ id │ name   │ status │ start_date          │ end_date            │      │
│  │ 1  │ 김철수  │ 활성   │ 2024-01-01 10:00    │ 9999-12-31 23:59    │◀─ current │
│  │ 1  │ 김철수  │ 휴면   │ 2024-03-15 14:30    │ 2024-03-15 14:29    │   history  │
│  │ 1  │ 김철수  │ 탈퇴   │ 2024-06-01 09:00    │ 2024-06-01 08:59    │   history  │
│  └─────────────────────────────────────────────────────────────────┘      │
│                                                                             │
│  [방식 3] 몽고DB 임베디드 이력                                               │
│  ────────────────────────────────                                           │
│  {                                                                            │
│    "_id": "C001",                                                            │
│    "name": "김철수",                                                          │
│    "status": "활성",                                                          │
│    "version_history": [          ← 이력을 배열로 임베디드                    │
│      { "status": "활성", "changed_at": "2024-01-01", "changed_by": "관리자A" },│
│      { "status": "휴면", "changed_at": "2024-03-15", "changed_by": "관리자B" } │
│    ]                                                                          │
│  }                                                                            │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Slowly Changing Dimension (SCD) 타입별 비교

┌─────────────────────────────────────────────────────────────────────────────┐
│                    SCD (Slowly Changing Dimension) 타입별 비교                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [Type 1: Overwrite - 이력 없음]                                            │
│  ─────────────────────────────────                                          │
│  • 이전 값을 덮어씀, 이력 추적 불가                                          │
│  • 단순하고 저장 공간 적게 듬                                                  │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │ before: { id: 1, city: "서울", region: "수도권" }                  │  │
│  │ after:  { id: 1, city: "성남", region: "수도권" } ← 서울→성남 덮어씀  │  │
│  │ → "서울" 이력은 사라짐                                               │  │
│  └─────────────────────────────────────────────────────────────────────┘  │
│                                                                             │
│  [Type 2: Add New Row - 새 행 추가]                                        │
│  ─────────────────────────────────────────                                  │
│  • 변경 시 새 행을 추가, 기존 행은 이력으로 남김                              │
│  • 가장 널리 사용되는 방식                                                    │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │ id │ city   │ region  │ start_date    │ end_date      │ is_current │ │
│  │ 1  │ 서울   │ 수도능  │ 2024-01-01    │ 2024-03-14     │ N          │ │
│  │ 1  │ 성남   │ 수도능  │ 2024-03-15    │ 9999-12-31     │ Y          │ │
│  └─────────────────────────────────────────────────────────────────────┘  │
│  → "서울" 이력 보존, 특정 날짜 기준 과거 데이터 조회 가능                     │
│                                                                             │
│  [Type 3: Add Attribute - 새 컬럼 추가]                                    │
│  ─────────────────────────────────────                                      │
│  • 이전 값을 별도 컬럼에 보관                                                 │
│  • 현재/이전 2개 상태만管理                                                  │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │ id │ city   │ previous_city │ region  │ effective_date           │  │
│  │ 1  │ 성남   │ 서울          │ 수도능  │ 2024-03-15                │  │
│  └─────────────────────────────────────────────────────────────────────┘  │
│  → 이전 값과 현재 값 동시에 조회 가능, 2개 이상 이력 불가                     │
│                                                                             │
│  [Type 4: Add Mini-Dimension - 미니 디メンション 추가]                      │
│  ─────────────────────────────────────────────                              │
│  • 자주 변경되는 속성을 별도 테이블로 분리                                    │
│  • 프로파일 속성 변화 추적에 유용                                             │
│                                                                             │
│  [Type 6: Hybrid - Type 1+2+3 조합]                                        │
│  ─────────────────────────────────                                          │
│  • 현재 값(Type 1), 이력(Type 2), 이전 값(Type 3) 모두 관리                 │
│  • 가장 유연하지만 복잡한 구조                                                │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

버저닝과 CDC 통합

┌─────────────────────────────────────────────────────────────────────────────┐
│                    버저닝 + CDC 통합 아키텍처                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [CDC (Change Data Capture) 개요]                                           │
│  ─────────────────────────────                                              │
│  • Database의 변경 로그(Redo Log, Transaction Log)를 실시간으로 캡처        │
│  • Debezium, AWS DMS, Oracle GoldenGate 등이 대표적                          │
│                                                                             │
│       ┌──────────────┐                                                      │
│       │  Source DB   │                                                      │
│       │ (MongoDB,    │──────▶ [CDC Agent] ──────▶ [Message Queue]         │
│       │  MySQL 등)   │       Debezium              Kafka                   │
│       └──────────────┘                                                      │
│                                                                             │
│  [버저닝 + CDC 통합 파이프라인]                                              │
│                                                                             │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐              │
│  │ Source  │───▶│  CDC    │───▶│ Stream  │───▶│ Versioned│              │
│  │ Table   │    │ Capture │    │ Process │    │  Target  │              │
│  │         │    │         │    │         │    │  Table   │              │
│  │customers│    │ Debezium│    │ Kafka    │    │with start│              │
│  │         │    │         │    │ Connect  │    │_date, end│              │
│  │         │    │         │    │          │    │_date     │              │
│  └─────────┘    └─────────┘    └─────────┘    └─────────┘              │
│      │                                                             │         │
│      │                                                             ▼         │
│      │                                                     ┌─────────────┐  │
│      │                                                     │ Point-in-Time│  │
│      │                                                     │  Recovery   │  │
│      │                                                     │ (과거시점복구) │  │
│      │                                                     └─────────────┘  │
│      │                                                             ▲         │
│      │                                                     ┌─────────────┐  │
│      │                                                     │  Audit Log  │  │
│      │                                                     │  (감사추적)  │  │
│      │                                                     └─────────────┘  │
│      │                                                             ▲         │
│      └─────────────────────────────────────────────────────── │         │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 버저닝 데이터 모델은 단순한 INSERT-Only 패턴으로 구현된다. UPDATE 대신 새 행을 INSERT하고, end_date나 is_current之类的 메타데이터로 버전 관리를 한다. CDC와 통합하면 소스 데이터베이스의 변경을 실시간으로 캡처하여 버전이력 테이블에 반영할 수 있다. 이를 통해 감사 추적, 과거 시점 복구, 데이터 분석 등의用例를 지원한다.

📢 섹션 요약: 버저닝 데이터 모델은 이중 테이블, 단일 테이블 버전 컬럼, 임베디드 이력 배열 등의 구현 방식이 있으며, SCD Type 1~6까지 다양한 전략으로 데이터 변경 이력을管理한다.


Ⅲ. 결론

버저닝 데이터 모델은 데이터의 시간에 따른 변경 이력을 명시적으로保存하는 핵심 기법이다. SCD Type 1~6까지 다양한 전략이 있으며, 비즈니스 요구사항과 regulatory compliance 요구에 따라 적절한 타입을 선택해야 한다. CDC(Change Data Capture)와 통합하면 실시간 데이터 변경 추적이 가능하며, 이를 통해 감사 로그, 과거 시점 복구, 데이터 분석 등의用例를 지원할 수 있다.

📢 섹션 요약: 버저닝 데이터 모델은 데이터 변경 이력 추적의 핵심 기법으로, SCD 전략과 CDC 통합을 통해 감사 추적과 과거 데이터 조회 기능 제공한다.


핵심 인사이트 ASCII 다이어그램 (Concept Map)

┌─────────────────────────────────────────────────────────────────────────────┐
│                    Versioning Data Model Concept Map                          │
│                                                                             │
│              ┌─────────────────────────────────┐                           │
│              │    Versioning Data Model       │                           │
│              │      (버저닝 데이터 모델)         │                           │
│              └───────────────┬─────────────────┘                           │
│                              │                                               │
│         ┌────────────────────┼────────────────────┐                        │
│         ▼                    ▼                    ▼                        │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐               │
│  │ SCD Type 1   │    │ SCD Type 2   │    │ SCD Type 3   │               │
│  │ (Overwrite)  │    │ (Add New Row)│    │ (Add Column) │               │
│  │              │    │              │    │              │               │
│  └──────────────┘    └──────────────┘    └──────────────┘               │
│         │                    │                    │                       │
│         └────────────────────┼────────────────────┘                        │
│                              ▼                                               │
│                   ┌─────────────────────┐                                  │
│                   │  CDC Integration     │                                  │
│                   │  + Audit Trail       │                                  │
│                   │  + Point-in-Time     │                                  │
│                   │  Recovery             │                                  │
│                   └─────────────────────┘                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

참고

  • 버저닝 데이터 모델은 데이터 변경 이력을 명시적으로保存한다.
  • SCD Type 1, 2, 3이 가장 많이 사용된다.
  • CDC와 통합하면 실시간 변경 추적이 가능하다.
  • 감사(Audit) 추적과 regulatory compliance에 필수적이다.
  • 저장 공간 overhead가 발생한다.
  • 쿼리 패턴에 따라 적절한 버저닝 전략을 선택해야 한다.