300. 스키마 온 라이트 vs 온 리드
핵심 인사이트 (3줄 요약)
- 본질: 스키마 온 라이트(Schema-on-Write)는 데이터를 저장하기 전에 스키마를 미리 정의하고 검증하는 방식이고, 스키마 온 리드(Schema-on-Read)는 데이터를 원시 형태로 저장한 후 읽을 때 스키마를 적용하는 방식이다.
- 가치: 스키마 온 라이트는 데이터 품질 보장, 스키마 온 리드는 분석 유연성과 다양한 데이터 유형 수용성을 제공한다.
- 융합: DW, 데이터 레이크, ETL, ELT, 데이터 모델링, Parquet, Avro, 데이터 품질과 밀접하게 연관된다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
개념 정의
스키마 온 라이트(Schema-on-Write)와 스키마 온 리드(Schema-on-Read)는 데이터를 저장소에 쓸(Write) 때와 저장소에서 읽을(Read) 때 스키마를 어떻게 처리할 것인지에 따른 두 가지 근본적으로 다른 데이터 관리 패러다임이다. 스키마 온 라이트는 데이터를 저장소에 기록하기 전에 스키마(테이블 정의, 데이터 타입, 제약조건 등)를 먼저 정의하고, 데이터가 해당 스키마를 준수하는지 검증한 후 저장한다. 반면 스키마 온 리드는 데이터의 스키마 정의 없이 원시 형태로 먼저 저장하고, 데이터를 읽을 때 분석 목적에 맞게 스키마를 적용한다.
필요성
비즈니스 환경에서 데이터의 활용 방식은 다양하다. 구조화된 정형 데이터에 대한 사전 정의된 보고서와 분석이 필요한 경우(예: 재무 보고), 데이터 품질과 일관성을 사전에 보장하는 스키마 온 라이트가 적합하다. 반면 SNS 데이터, IoT 센서 데이터, 로그 파일 등 비정형 또는 반정형 데이터에 대한 탐색적 분석이나 머신러닝 모델 훈련이 필요한 경우, 분석 전에 스키마를 정의하기 어려운 경우가 많다. 스키마 온 리드는 이러한 상황에서 데이터를 먼저 저장하고 나중에 스키마를 적용할 수 있는 유연성을 제공한다.
배경
스키마 온 라이트는 전통적인 관계형 데이터베이스 관리 시스템(RDBMS)에서 채택한 방식이다. SQL 테이블을 생성할 때 스키마를 정의하고, INSERT/UPDATE 시마다 데이터가 스키마를 준수하는지 검증한다. 데이터 웨어하우스도 이 방식을 채택하여 ETL 과정에서 데이터 정제와 스키마 매핑을 수행한다.
스키마 온 리드는 데이터 레이크의 등장과 함께 주목받기 시작했다. 2010년대 하둡과 NoSQL의 확산으로 다양한 유형의 데이터를/schema 없이 저장하려는 니즈가 증가했으며, 분석 시점에 스키마를 적용하는 유연성이 강점이 되었다. Apache Parquet, Apache Avro 같은 columnar 및 serialization 형식이 스키마 온 리드 저장소의 효율적인 데이터 관리에 활용되고 있다.
비유
스키마 온 라이트는新建아파트에 입주 전에户型图(스키마)를 미리 确定하고, 가구(데이터)가户型图에 맞는지 확인한 후 들어가는 것과 같다. 모든 것이 계획대로整然としており品質도 보장되지만, 입주 전에很多东西를 결정해야 하므로 유연성이 제한된다.
스키마 온 리드는 tenant先で公寓복도에 가구들을 올려놓고, 나중에 방을 쓸 때마다 그때그때 배치도(스키마)를 정하는 것과 같다. 어떤 가구든 일단 저장할 수 있어서 유연하지만, 나중에 방을 쓸 때 가구가 서로 안 맞거나 (스키마 불일치) 찾기 어려울 수 있다.
📢 섹션 요약: 스키마 온 라이트는 저장 시 스키마를 검증하여 데이터 품질을 보장하고, 스키마 온 리드는 읽기 시 스키마를 적용하여 다양한 데이터 유형과 분석 유연성을 제공한다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
두 방식의 동작 비교
┌─────────────────────────────────────────────────────────────────────────────┐
│ 스키마 온 라이트 vs 스키마 온 리드 동작 비교 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ [스키마 온 라이트 (Schema-on-Write)] │
│ ───────────────────────────────────── │
│ │
│ ① 스키마 정의 (Schema Creation) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ CREATE TABLE customers ( │ │
│ │ customer_id INT PRIMARY KEY, │ │
│ │ name VARCHAR(100), │ │
│ │ email VARCHAR(255), │ │
│ │ created_at TIMESTAMP │ │
│ │ ); │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ② 데이터 적재 시 검증 (Write Validation) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ INSERT INTO customers VALUES (1, '김철수', 'a@example.com', now()); │ │
│ │ → email이 VARCHAR(255) 범위内? → YES → 저장 ✓ │ │
│ │ │ │
│ │ INSERT INTO customers VALUES (2, NULL, 'b@example.com', now()); │ │
│ │ → name이 NOT NULL 위반 → NO → 오류 발생 ✗ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ③ 읽기 (Read - 이미 검증된 데이터) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SELECT * FROM customers; │ │
│ │ → 저장 시 검증 완료 → 빠른 읽기 가능 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ [스키마 온 리드 (Schema-on-Read)] │
│ ───────────────────────────────────── │
│ │
│ ① 원시 데이터 저장 (Raw Storage - 스키마 없이) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ // 파일 형식: JSON Lines, Parquet, Avro 등 │ │
│ │ {customer_id: 1, name: "김철수", email: "a@example.com"} │ │
│ │ {customer_id: 2, name: "이영희", email: "b@example.com", phone: "010..."}| │
│ │ {customer_id: 3, nickname: "영희", email: "c@example.com"} │ │
│ │ //phone, nickname 등 schema 없는 필드도 그냥 저장됨 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ② 읽기 시 스키마 정의 (Read-time Schema Definition) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ // 분석 1: email만 필요할 때 │ │
│ │ SELECT customer_id, email FROM raw_customers; │ │
│ │ │ │
│ │ // 분석 2: phone도 필요할 때 │ │
│ │ SELECT customer_id, COALESCE(name, nickname) as name, email, phone │ │
│ │ FROM raw_customers; │ │
│ │ // →COALESCE로 name/nickname 통합, phone이 없으면 NULL 처리 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ③ 스키마 불일치 handling │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ // customer_id 3은 nickname 필드만 있어 name이 없음 │ │
│ │ → 스키마 온 리드는 이를 오류로 처리하지 않고 NULL로 취급 │ │
│ │ → 데이터 손실 없이 모든 레코드 조회 가능 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
데이터 포맷과 스키마 온 리드
┌─────────────────────────────────────────────────────────────────────────────┐
│ 스키마 온 리드友善 데이터 포맷 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ [Parquet 형식] │
│ ───────────── │
│ • Columnar 저장 형식 (열 기반 저장) │
│ • 파일 헤더에 스키마를 내장 (self-describing) │
│ • 읽기 시 스키마 정보를 활용 가능 │
│ • 분석 查询에 최적 (열 단위 압축, 스킵) │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ // Parquet 파일 구조 │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ File Header: Schema (customer_id:INT, name:STRING, ...) │ │ │
│ │ ├─────────────────────────────────────────────────────────────┤ │ │
│ │ │ Row Group 1 │ │ │
│ │ │ Column Chunk: customer_id (INT) │ │ │
│ │ │ Column Chunk: name (STRING) │ │ │
│ │ │ Column Chunk: email (STRING) │ │ │
│ │ ├─────────────────────────────────────────────────────────────┤ │ │
│ │ │ Row Group 2 │ │ │
│ │ │ ... │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ [Avro 형식] │
│ ────────── │
│ • 행 기반 저장 형식 (Row-based) │
│ • JSON 또는 binary 형태로 스키마를 별도 파일로 관리 │
│ • 스키마 evolution (호환 가능한 스키마 변경) 지원 │
│ • Kafka, streaming 데이터에 적합 │
│ │
│ [데이터 레이크에서의 스키마 온 리드 메타데이터 관리] │
│ ──────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Apache Hive Metastore / AWS Glue Data Catalog │ │
│ │ ────────────────────────────────────────────────────────────────│ │
│ │ │ │
│ │ Table Metadata: │ │
│ │ ┌───────────────────────────────────────────────────────────────┐ │ │
│ │ │ Table Name: raw_customers │ │ │
│ │ │ Location: s3://datalake/raw/bronze/customers/ │ │ │
│ │ │ Format: Parquet │ │ │
│ │ │ Schema: │ │ │
│ │ │ customer_id: int (nullable) │ │ │
│ │ │ name: string (nullable) │ │ │
│ │ │ email: string (nullable) │ │ │
│ │ │ _partition_date: string (generated) │ │ │
│ │ │ Partitioned by: _partition_date │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ※ 파티션, location, format 등 메타데이터로 데이터Discovery 지원 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
비교 결정 트리
┌─────────────────────────────────────────────────────────────────────────────┐
│ 스키마 온 라이트 vs 온 리드 선택 결정 트리 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────┐ │
│ │ 데이터 분석 방식이 무엇인가? │ │
│ └───────────────┬─────────────────────┘ │
│ 사전 정의된 분석 │ │ 분석 시점不确定/다양함 │
│ (보고서, OLAP) │ │ (탐색적 분석, ML) │
│ ▼ │ ▼ │
│ ┌────────────────┴────────────────┐ │
│ │ 스키마 온 라이트 │ │
│ │ ✅ 사전 검증으로 품질 보장 │ │
│ │ ✅ 일관된 데이터 구조 │ │
│ │ ✅ 빠른 읽기 성능 │ │
│ │ ❌ 유연성 제한 │ │
│ │ ❌ ETL 사전 처리 시간 │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ 스키마 온 리드 │ │
│ │ ✅ 다양한 데이터 수용 │ │
│ │ ✅ 분석 시점 유연성 │ │
│ │ ✅ 데이터 수집 속도 빠름 │ │
│ │ ❌ 사후 스키마 관리 필요 │ │
│ │ ❌ 데이터 품질 위험 │ │
│ └────────────────────────────────┘ │
│ │
│ [실무 활용: Hybrid 접근] │
│ ─────────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 데이터 레이크에서 Bronze(Raw) → Silver(Cleansed) → Gold(Analysis) │ │
│ │ │ │
│ │ Bronze Zone: 스키마 온 리드 (원시 데이터 저장) │ │
│ │ Silver Zone: 스키마 온 라이트-ish (정제 후 검증된 데이터) │ │
│ │ Gold Zone: 분석 가능 상태 ( schema 적용된 데이터) │ │
│ │ │ │
│ │ → 수집 단계에서는 유연성(온 리드), 분석 단계에서는 품질(온 라이트) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 스키마 온 라이트와 스키마 온 리드는 각기 다른 장단점을 가진다. 스키마 온 라이트는 데이터 품질을 사전에 보장하지만 유연성이 제한되고, 스키마 온 리드는 유연성을 제공하지만 사후에 스키마 관리가 필요하다. 실무에서는 Bronze-Raw, Silver-Cleansed, Gold-Analysis 3단계로 나누어, 수집 단계에서는 온 리드의 유연성을, 분석 단계에서는 온 라이트의 품질을 적용하는 hybrid 접근이 흔히 사용된다.
📢 섹션 요약: 스키마 온 라이트는 사전 데이터 품질 보장과 일관된 구조를, 스키마 온 리드는 다양한 데이터 수용과 분석 유연성을 제공하며, 실무에서는 hybrid 접근이 흔히 사용된다.
Ⅲ. 결론
스키마 온 라이트와 스키마 온 리드는 데이터를 저장하고 읽는 방식에서根本적으로 다른 패러다임이다. 스키마 온 라이트는 사전에 스키마를 정의하여 데이터 품질을 보장하지만 분석의 유연성이 제한되고, 스키마 온 리드는 데이터를 원시 형태로 저장하여 다양한 분석을 가능하게 하지만 사후 스키마 관리가 필요하다. 실무에서는 데이터 레이크의 Bronze-Raw, Silver-Cleansed, Gold-Analysis 구조처럼 hybrid 접근을 취하여, 수집 단계에서는 온 리드의 유연성을, 분석 단계에서는 온 라이트의 품질을 적용하는 것이 일반적이다.
📢 섹션 요약: 스키마 온 라이트와 온 리드는 각각 데이터 품질과 분석 유연성 사이의 트레이드오프이며, 실무에서는 beide의 장점을活用하는 hybrid 접근이 권장된다.
핵심 인사이트 ASCII 다이어그램 (Concept Map)
┌─────────────────────────────────────────────────────────────────────────────┐
│ Schema-on-Write vs Schema-on-Read Concept Map │
│ │
│ ┌─────────────────────────────────┐ │
│ Schema-on-Write vs Schema-on-Read │ │
└───────────────┬─────────────────┘ │
│ │ │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Schema-on- │ │ Schema-on- │ │ Hybrid │ │
│ │ Write │ │ Read │ │ Approach │ │
│ │ │ │ │ │ (실무권장) │ │
│ │ ✅ 품질보장 │ │ ✅ 유연성 │ │ Bronze: 온리드│ │
│ │ ✅ 일관성 │ │ ✅ 빠른수집 │ │ Silver: 정제 │ │
│ │ ❌ 제한적 │ │ ❌ 사후관리 │ │ Gold: 분석 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └────────────────────┼────────────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ DW / Data Lake │ │
│ │ (목적에 맞게 선택)│ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
참고
- 스키마 온 라이트는 저장 시 스키마를 검증하고, 온 리드는 읽기 시 적용한다.
- 온 라이트는 데이터 품질과 일관성을, 온 리드는 유연성과 다양한 데이터 수용성을 제공한다.
- Parquet, Avro 등은 스키마 온 리드를支援하는 self-describing 형식이다.
- 실무에서는 Bronze-Raw, Silver-Cleansed, Gold-Analysis hybrid 접근이 권장된다.
- 데이터 레이크는 온 리드, 데이터 웨어하우스는 온 라이트에 기반한다.
- 메타데이터 카탈로그(Hive Metastore, Glue Catalog) 활용이 스키마 온 리드 관리에 필수적이다.