264. 분할 투명성 (Fragmentation/Partition Transparency)

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

  1. 본질: 분할 투명성은 데이터가 수평 분할(행 단위)이나 수직 분할(열 단위)로 물리적으로 나뉘어져 있음을 사용자가 인식할 필요 없이, 단일 테이블처럼 조회할 수 있게 하는 투명성 규칙이다.
  2. 가치: 사용자에게 복잡한 분할 구조를 은폐하여 쿼리 작성을 단순화하고, 분할로 인한 조인이나 집합 연산의 복잡성을 시스템이 자동으로 처리하게 한다.
  3. 융합: 수평 분할, 수직 분할, 분산 조인, 데이터 분할 기법, 글로벌 카탈로그와 밀접하게 연관된다.

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

개념 정의

분할 투명성(Fragmentation Transparency)은 분산 데이터베이스에서 데이터가 여러 조각(Fragment)으로 분할되어 저장되어 있음을 사용자가 인식할 필요 없이, 단일 논리적 테이블처럼 쿼리할 수 있게 하는 투명성 규칙이다. 수평 분할(Horizontal Fragmentation)과 수직 분할(Vertical Fragmentation) 모두를 포함한다.

필요성

대규모 데이터베이스에서는 데이터를 분할하여 저장 관리해야 하는 경우가 많다. 그러나 분할 구조를 사용자에게 노출하면, 쿼리 작성 시 각 분할을 명시적으로 언급해야 하고, UNION이나 JOIN으로 결과를 병합해야 하는 등 부담이 증가한다. 분할 투명성을 통해 이러한 복잡성을 은폐하고 사용자 편의성을 높일 수 있다.

배경

분할 투명성은 1980년대 분산 데이터베이스 연구에서 비롯되었으며, 이후 다양한 분산 데이터베이스 시스템에서 구현되고 있다. Oracle, PostgreSQL, MongoDB, Cassandra 등 주요 데이터베이스에서 다양한 형태의 분할 투명성을 제공한다.

비유

분할 투명성은大型图书馆의中央目录系统和같다. 방문객은 책이 여러 층, 여러 구역에 나뉘어 있음을 모르더라도 중앙目录에서 찾고 싶은 책을 검색하면 된다. 도서관에서 실제로 책이 어디에 위치하는지는系统가 자동으로 관리한다.

📢 섹션 요약: 분할 투명성은 데이터의 물리적 분할 구조(수평/수직)를 은폐하여 사용자에게 단일 테이블처럼 보이게 하며, 복잡한 분할 관리 작업을 시스템이 자동으로 처리하게 한다.


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

수평 분할 (Horizontal Fragmentation)

┌─────────────────────────────────────────────────────────────────────────────┐
│                    수평 분할 (Horizontal Fragmentation)                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [정의]                                                                    │
│  • 튜플(행) 단위로 데이터를 분할                                              │
│  • 각 분할은 원래 테이블의 일부 행을 포함                                    │
│  • 분할 조건: WHERE 절 조건 기반                                             │
│                                                                             │
│  [예시]                                                                    │
│                                                                             │
│  원래 테이블: customers                                                     │
│  ┌──────────┬──────────┬──────────┬──────────┐                             │
│  │customer_id│ name    │ region   │ balance  │                             │
│  ├──────────┼──────────┼──────────┼──────────┤                             │
│  │ C001     │ Kim      │ SEOUL   │ 1000     │                             │
│  │ C002     │ Lee      │ BUSAN   │ 2000     │                             │
│  │ C003     │ Park     │ SEOUL   │ 1500     │                             │
│  │ C004     │ Choi     │ INCHEON │ 3000     │                             │
│  │ C005     │ Jung     │ BUSAN   │ 2500     │                             │
│  └──────────┴──────────┴──────────┴──────────┘                             │
│                                                                             │
│  수평 분할 결과:                                                             │
│                                                                             │
│  customers_seoul (region = 'SEOUL'):                                        │
│  ┌──────────┬──────────┬──────────┬──────────┐                             │
│  │ C001    │ Kim      │ SEOUL   │ 1000     │                             │
│  │ C003    │ Park     │ SEOUL   │ 1500     │                             │
│  └──────────┴──────────┴──────────┴──────────┘                             │
│                                                                             │
│  customers_busan (region = 'BUSAN'):                                         │
│  ┌──────────┬──────────┬──────────┬──────────┐                             │
│  │ C002    │ Lee      │ BUSAN   │ 2000     │                             │
│  │ C005    │ Jung     │ BUSAN   │ 2500     │                             │
│  └──────────┴──────────┴──────────┴──────────┘                             │
│                                                                             │
│  customers_incheon (region = 'INCHEON'):                                    │
│  ┌──────────┬──────────┬──────────┬──────────┐                             │
│  │ C004    │ Choi     │ INCHEON │ 3000     │                             │
│  └──────────┴──────────┴──────────┴──────────┘                             │
│                                                                             │
│  [사용자 쿼리]                                                              │
│  SELECT * FROM customers;                                                  │
│  → 시스템이 모든 분할을 UNION하여 결과 반환 (분할 투명성)                      │
│                                                                             │
│  SELECT * FROM customers WHERE region = 'SEOUL';                            │
│  → 시스템이 해당 분할만 접근 (분할 프루닝 - 투명성 + 성능 최적화)               │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

수직 분할 (Vertical Fragmentation)

┌─────────────────────────────────────────────────────────────────────────────┐
│                    수직 분할 (Vertical Fragmentation)                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [정의]                                                                    │
│  • 속성(열) 단위로 데이터를 분할                                              │
│  • 각 분할은 원래 테이블의 일부 컬럼을 포함                                    │
│  • 분할 시 반드시 Primary Key를 모든 분할에 포함해야 함 (재조합 용이성)         │
│                                                                             │
│  [예시]                                                                    │
│                                                                             │
│  원래 테이블: employees                                                     │
│  ┌──────────┬──────────┬──────────┬──────────┬──────────┐                 │
│  │ emp_id   │ name     │ email    │ phone    │ salary   │                 │
│  ├──────────┼──────────┼──────────┼──────────┼──────────┤                 │
│  │ E001     │ Kim      │a@a.com  │ 010-1111 │ 5000     │                 │
│  │ E002     │ Lee      │b@b.com  │ 010-2222 │ 6000     │                 │
│  │ E003     │ Park     │c@c.com  │ 010-3333 │ 5500     │                 │
│  └──────────┴──────────┴──────────┴──────────┴──────────┘                 │
│                                                                             │
│  수직 분할 결과:                                                             │
│                                                                             │
│  employees_main (emp_id, name):                                            │
│  ┌──────────┬──────────┐                                                  │
│  │ emp_id   │ name     │                                                  │
│  ├──────────┼──────────┤                                                  │
│  │ E001     │ Kim      │                                                  │
│  │ E002     │ Lee      │                                                  │
│  │ E003     │ Park     │                                                  │
│  └──────────┴──────────┘                                                  │
│                                                                             │
│  employees_contact (emp_id, email, phone):                                 │
│  ┌──────────┬──────────┬──────────┐                                       │
│  │ emp_id   │ email    │ phone    │                                       │
│  ├──────────┼──────────┼──────────┤                                       │
│  │ E001     │a@a.com  │ 010-1111 │                                       │
│  │ E002     │b@b.com  │ 010-2222 │                                       │
│  │ E003     │c@c.com  │ 010-3333 │                                       │
│  └──────────┴──────────┴──────────┘                                       │
│                                                                             │
│  employees_salary (emp_id, salary):                                        │
│  ┌──────────┬──────────┐                                                  │
│  │ emp_id   │ salary   │                                                  │
│  ├──────────┼──────────┤                                                  │
│  │ E001     │ 5000     │                                                  │
│  │ E002     │ 6000     │                                                  │
│  │ E003     │ 5500     │                                                  │
│  └──────────┴──────────┘                                                  │
│                                                                             │
│  [재조합]                                                                  │
│  SELECT * FROM employees;                                                  │
│  → emp_id 기준 JOIN하여 전체 컬럼 반환                                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

분할 투명성 동작 과정

┌─────────────────────────────────────────────────────────────────────────────┐
│                    분할 투명성 동작 과정                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [분할 투명성 미제공 시]                                                    │
│  ─────────────────────────                                                 │
│  SELECT * FROM customers_seoul                                             │
│  UNION ALL                                                                 │
│  SELECT * FROM customers_busan                                             │
│  UNION ALL                                                                 │
│  SELECT * FROM customers_incheon;                                           │
│  ※ 사용자가 분할 구조를 알고 있어야 함                                        │
│                                                                             │
│  [분할 투명성 제공 시]                                                      │
│  ────────────────────────                                                 │
│  SELECT * FROM customers;                                                  │
│  ※ 시스템이 자동으로 모든 분할 접근 후 결과 통합                                │
│                                                                             │
│  [동작 과정]                                                                │
│                                                                             │
│       사용자 쿼리: SELECT * FROM customers WHERE region = 'SEOUL'            │
│                           │                                                │
│                           ▼                                                │
│       ┌──────────────────────────────────────────────────────┐             │
│       │              분산 쿼리 최적화기                        │             │
│       │  1. 글로벌 카탈로그에서 customers 분할 정보 확인       │             │
│       │  2. WHERE 조건 분석: region = 'SEOUL'                │             │
│       │  3. 해당 분할만 접근 결정 (분할 프루닝)                │             │
│       │  4. customers_seoul에만 쿼리 실행                      │             │
│       └──────────────────────────────────────────────────────┘             │
│                           │                                                │
│                           ▼                                                │
│                    결과 반환 (SEOUL 고객만)                                   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 분할 투명성의 핵심은 분산 쿼리 최적화기이다. 사용자의 쿼리를 분석하여, 글로벌 카탈로그의 분할 정보를 참조하고, 최적의 분할만 접근하도록 계획한다. WHERE 조건이 분할 기준과 일치하면 해당 분할만 접근하는 "분할 프루닝"을 수행하여 성능을 최적화한다. SELECT *와 같이 모든 분할의 데이터가 필요하면, 모든 분할에 접근 후 UNION하여 결과를 반환한다.

📢 섹션 요약: 분할 투명성은 분산 쿼리 최적화기를 통해 구현되며, WHERE 조건과 분할 기준을 분석하여 필요한 분할만 접근하는 분할 프루닝으로 성능도 최적화한다.


Ⅲ. 구현 및 실무 응용 (Implementation & Practice)

MongoDB의 분할 투명성

// MongoDB Sharded Cluster: 분할 투명성 제공

// 컬렉션 분할 설정
sh.enableSharding("mydb")

// 수평 분할 (Sharding)
sh.shardCollection("mydb.orders", {customer_id: "hashed"})
// 또는
sh.shardCollection("mydb.orders", {order_date: 1})
// → order_date 기반 범위 분할

// 사용자 쿼리 (분할 투명성)
db.orders.find({})  // 전체 조회 - 모든 Shard 접근
db.orders.find({customer_id: "C001"})  // 특정 고객 - 해당 Shard만 접근
db.orders.find({order_date: {$gte: ISODate("2024-01-01")}})
  // 범위 조회 - 일부 Shard만 접근 (분할 프루닝)

// ※ 사용자는 Shard 구조를 인식할 필요 없음
// ※ MongoDB가 자동으로 분할 정보를 참조하여 최적의Shard에 접근

PostgreSQL의 파티셔닝

-- PostgreSQL: 테이블 파티셔닝 (분할 투명성 지원)

-- 부모 테이블 생성
CREATE TABLE orders (
    order_id SERIAL,
    customer_id INTEGER,
    order_date DATE,
    total DECIMAL
) PARTITION BY RANGE (order_date);

-- 파티션 생성
CREATE TABLE orders_2024_q1 PARTITION OF orders
    FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');

CREATE TABLE orders_2024_q2 PARTITION OF orders
    FOR VALUES FROM ('2024-04-01') TO ('2024-07-01');

CREATE TABLE orders_2024_q3 PARTITION OF orders
    FOR VALUES FROM ('2024-07-01') TO ('2024-10-01');

CREATE TABLE orders_2024_q4 PARTITION OF orders
    FOR VALUES FROM ('2024-10-01') TO ('2025-01-01');

-- 사용자 쿼리 (분할 투명성)
SELECT * FROM orders WHERE order_date >= '2024-01-01';
-- → PostgreSQL이 자동으로 관련 파티션만 접근 (분할 프루닝)
-- → 사용자는 파티션을 인식할 필요 없음

-- 확인: EXPLAIN으로 분할 접근 확인
EXPLAIN SELECT * FROM orders WHERE order_date >= '2024-01-01';
-- → Append on orders_2024_q1, orders_2024_q2, ...
--   (해당 파티션만 스캔)

수직 분할: 마스터-디테일 패턴

-- Oracle/PostgreSQL: 수직 분할 예시

-- 메인 테이블: 고객 기본 정보
CREATE TABLE customers_main (
    customer_id INTEGER PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);

-- 디테일 테이블: 고객 상세 정보
CREATE TABLE customers_detail (
    customer_id INTEGER PRIMARY KEY REFERENCES customers_main,
    phone VARCHAR(20),
    address TEXT,
    notes TEXT
);

-- 뷰를 통한 투명성 제공
CREATE VIEW customers AS
SELECT
    c.customer_id,
    c.name,
    c.email,
    d.phone,
    d.address,
    d.notes
FROM customers_main c
LEFT JOIN customers_detail d ON c.customer_id = d.customer_id;

-- 사용자 쿼리 (투명성)
SELECT * FROM customers WHERE customer_id = 1;
-- → 시스템이 조인 자동 수행 (사용자는 수직 분할 인식 불필요)

📢 섹션 요약: MongoDB, PostgreSQL, Oracle 등 주요 DB에서 분할 투명성을 제공하며, 분산 쿼리 최적화, 파티셔닝, 뷰 등을 통해 구현된다.


Ⅳ. 품질 관리 및 테스트 (Quality & Testing)

분할 투명성 테스트

┌─────────────────────────────────────────────────────────────────────────────┐
│                    분할 투명성 관련 품질 테스트 항목                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [분할 프루닝 테스트]                                                        │
│  ──────────────────                                                         │
│  □ WHERE 조건이 분할 기준과 일치할 때 올바른 분할만 접근하는지 확인              │
│  □ 분할 프루닝 미작동 시 성능 저하 확인                                        │
│  □ 범위 查询 시 필요한 파티션만 접근하는지 확인                                │
│                                                                             │
│  [완전한 테이블 조회 테스트]                                                  │
│  ─────────────────────                                                      │
│  □ SELECT * 시 모든 분할에서 데이터 조회 확인                                  │
│  □ UNION/JOIN 결과 정확성 확인                                              │
│  □ 결과 건수 정확성 확인                                                     │
│                                                                             │
│  [분할 변경 테스트]                                                          │
│  ──────────────                                                             │
│  □ 새 분할 추가 시 기존 쿼리 동작 확인                                        │
│  □ 분할 제거/분할合并 시 데이터 정확성 확인                                    │
│  □ 분할 기준 변경 시 쿼리 영향 분석                                           │
│                                                                             │
│  [성능 테스트]                                                               │
│  ──────────                                                                 │
│  □ 분할 투명성 오버헤드 측정                                                  │
│  □ 분할 수 증가에 따른 성능 변화                                             │
│  □ 분할 프루닝 효과 측정                                                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

📢 섹션 요약: 분할 투명성 테스트는 분할 프루닝, 완전한 테이블 조회, 분할 변경, 성능을 포함해야 하며, 분할 구조 변경 시 동작을 확인해야 한다.


Ⅴ. 결론

분할 투명성은 수평/수직 분할 구조를 사용자에게 은폐하여 단일 테이블처럼 쿼리할 수 있게 한다. 분산 쿼리 최적화기를 통해 필요한 분할만 접근하는 분할 프루닝으로 성능도 최적화한다. 그러나 분할 구조가 복잡해질수록 최적화기의 부담이 증가하므로, 분할 전략 설계 시 투명성과 성능 사이의 균형을 고려해야 한다.

📢 섹션 요약: 분할 투명성은 분할 구조를 은폐하여 사용자 편의성을 높이지만, 분할 전략 설계 시 분할 프루닝 효과와 시스템 복잡도 사이의 균형 고려가 필요하다.


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

┌─────────────────────────────────────────────────────────────────────────────┐
│                Fragmentation Transparency Concept Map                        │
│                                                                             │
│              ┌───────────────────────────┐                                   │
│              │ Fragmentation Transparency│                                   │
│              │     (분할 투명성)          │                                   │
│              └───────────┬───────────────┘                                   │
│                          │                                                  │
│       ┌──────────────────┼──────────────────┐                             │
│       ▼                  ▼                  ▼                              │
│  ┌─────────┐       ┌─────────┐       ┌─────────┐                         │
│  │ Horizontal│       │ Vertical │       │Query    │                         │
│  │(수평분할)│       │(수직분할)│       │Optimizer│                         │
│  │  행 단위  │       │  열 단위  │       │(분산최적화)│                      │
│  └────┬────┘       └────┬────┘       └────┬────┘                         │
│       │                  │                  │                               │
│       ▼                  ▼                  ▼                               │
│  ┌─────────────────────────────────────────────────────┐                  │
│  │              분할 프루닝 (Partition Pruning)        │                  │
│  │        WHERE 조건과 분할 기준 매칭하여 최적 분할 접근  │                  │
│  └─────────────────────────────────────────────────────┘                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

참고

  • 분할 투명성은 수평/수직 분할 구조를 사용자에게 은폐한다.
  • 분산 쿼리 최적화기가 분할 정보를 참조하여 최적의 접근 경로를 결정한다.
  • 분할 프루닝으로 WHERE 조건과 일치하는 분할만 접근하여 성능을 최적화한다.
  • 수직 분할 시 Primary Key를 모든 분할에 포함해야 조인/재조합이 가능하다.