← 목록으로
단계 08

웨어하우스 · 레이크하우스 · SQL 분석

스키마 설계(스타 스키마), 배치 ETL, 분석형 SQL(윈도우 함수), 레이크하우스와 오픈 테이블 포맷(Iceberg/Delta).

웨어하우스 vs 레이크 vs 레이크하우스

데이터 웨어하우스데이터 레이크레이크하우스
저장전용 DB (Redshift, BigQuery, Snowflake)S3/HDFS 파일S3/HDFS 파일 + 테이블 포맷
스키마쓰기 시 강제 (schema-on-write)읽을 때 해석 (schema-on-read)둘 다
강점빠른 SQL, 정합성저렴, 유연, 원본 보존레이크 비용 + 웨어하우스 기능
약점비쌈, 비정형 취약트랜잭션·갱신 없음 → "데이터 늪"비교적 새 기술

스키마 설계: 스타 스키마

분석용 테이블은 정규화보다 질문하기 쉬운 구조가 우선.

              dim_date
                 │
 dim_customer ── fact_sales ── dim_product
                 │
              dim_region
  • Fact: 측정값 (금액, 수량) + 각 차원의 키. 크고 길다.
  • Dimension: 설명 속성 (고객 이름, 지역명, 날짜의 요일). 작고 넓다.

배치 ETL

# 매일 새벽 실행되는 전형적인 배치 잡
raw = spark.read.json("s3a://lake/raw/orders/date=2026-08-28/")
clean = (raw.dropDuplicates(["order_id"])
            .withColumn("amount", F.col("amount").cast("double"))
            .filter(F.col("amount") > 0))
clean.write.mode("overwrite").parquet("s3a://lake/cleaned/orders/date=2026-08-28/")

오케스트레이션(매일 실행, 실패 시 재시도)은 Airflow 같은 도구가 담당 — 이 수업에선 개념만.

분석형 SQL

-- 지역별 월 매출과 전월 대비 증감 (윈도우 함수)
SELECT region, month, total,
       total - LAG(total) OVER (PARTITION BY region ORDER BY month) AS diff,
       RANK() OVER (PARTITION BY month ORDER BY total DESC) AS rnk
FROM (
  SELECT region, date_trunc('month', order_date) AS month, SUM(amount) AS total
  FROM fact_sales GROUP BY 1, 2
);

윈도우 함수(LAG, RANK, SUM() OVER)는 분석 SQL의 핵심. Spark SQL, DuckDB 모두 지원.

오픈 테이블 포맷: Iceberg / Delta

Parquet 파일 더미 위에 메타데이터 계층을 얹어 "테이블"처럼 만드는 기술.

얻는 것:

  • ACID 트랜잭션 — 쓰는 중에 읽어도 깨진 데이터 안 보임
  • UPDATE / DELETE / MERGE — 파일 기반인데 행 단위 수정 가능
  • 타임 트래블VERSION AS OF 3 으로 과거 스냅샷 조회
  • 스키마 진화 — 열 추가/이름 변경을 안전하게
# Delta Lake 예 (pip install delta-spark)
df.write.format("delta").mode("overwrite").save("/lake/sales_delta")
spark.read.format("delta").option("versionAsOf", 0).load("/lake/sales_delta")

Iceberg와 Delta는 목적이 같고 세부 설계가 다릅니다. 요즘은 둘 다 읽는 엔진이 늘고 있습니다(Spark, Trino, DuckDB, Snowflake...).

연습 과제

  1. 매출 CSV를 fact/dim 테이블로 나눠 Parquet 저장
  2. Spark SQL로 윈도우 함수 쿼리 3개 작성
  3. (선택) Delta로 저장 → UPDATE 실행 → 이전 버전 읽어 비교