<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>김신건의 로그 - 위키 / data-engineering</title><description>&apos;data-engineering&apos; 카테고리 위키 페이지 최신 업데이트</description><link>https://shinkeonkim.com/</link><language>ko-KR</language><item><title>Apache Parquet</title><link>https://shinkeonkim.com/wiki/data-engineering/apache-parquet/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/apache-parquet/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Apache Parquet&lt;/strong&gt; 은 &lt;em&gt;분석 쿼리에 최적화된 오픈소스 컬럼형 이진 파일 포맷&lt;/em&gt;. 2013년 Twitter + Cloudera 가 Google Dremel 논문 (2010) 을 참고해 발표. 현재 [[data-warehouse|데이터 웨어하우스]] / data lake 의 사실상 표준 저장 포맷.&lt;/p&gt;
&lt;p&gt;같은 데이터를 CSV/JSON 대비 &lt;em&gt;10-100배 작게&lt;/em&gt;, 분석 쿼리를 &lt;em&gt;10-100배 빠르게&lt;/em&gt; 실행.&lt;/p&gt;
&lt;h2 id=&quot;왜-컬럼형인가&quot;&gt;왜 컬럼형인가&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Row-based (CSV, JSON, Avro):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Row 1: [id=1, name=&quot;A&quot;, age=30, ..., col50]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Row 2: [id=2, name=&quot;B&quot;, age=25, ..., col50]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SELECT AVG(age) → 모든 컬럼을 읽고 age 만 뽑음.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Column-based (Parquet, ORC):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  id:   [1, 2, 3, ...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  name: [A, B, C, ...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  age:  [30, 25, 40, ...]  ← 이 컬럼만 스캔&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SELECT AVG(age) → age 컬럼만 I/O. 나머지 스킵.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;컬럼형의 세 가지 이점&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;I/O 절감&lt;/strong&gt; - 필요한 컬럼만 읽음 (컬럼 프로젝션)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;압축률&lt;/strong&gt; - 같은 타입/유사값이 연속 -&gt; 사전, RLE, delta 압축이 잘 먹힘 (5-10배)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU 효율&lt;/strong&gt; - 같은 타입이 연속 -&gt; SIMD 벡터 명령, late materialization&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;파일-구조&quot;&gt;파일 구조&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File[&quot;Parquet File&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Header[&quot;Magic &apos;PAR1&apos;&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RG1[&quot;Row Group 1&amp;#x3C;br/&gt;(128 MB - 1 GB)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RG2[&quot;Row Group 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RGN[&quot;Row Group N&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Footer[&quot;Footer&amp;#x3C;br/&gt;(schema + metadata + statistics)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Trailer[&quot;Magic &apos;PAR1&apos;&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; Header&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; RG1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; RG2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; RGN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; Footer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; Trailer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RG1 --&gt; CC1[&quot;Column Chunk 1&amp;#x3C;br/&gt;(컬럼 A 데이터)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RG1 --&gt; CC2[&quot;Column Chunk 2&amp;#x3C;br/&gt;(컬럼 B 데이터)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RG1 --&gt; CCN[&quot;Column Chunk N&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CC1 --&gt; Page1[&quot;Data Page 1&amp;#x3C;br/&gt;(1-10 MB)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CC1 --&gt; Page2[&quot;Data Page 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CC1 --&gt; Dict[&quot;Dictionary Page (optional)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;계층&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;크기 (권장)&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;역할&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;File&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;임의&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;하나의 물리 파일 (&lt;code&gt;.parquet&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Row Group&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;128 MB - 1 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;수평 파티션, 병렬 read/write 단위&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Column Chunk&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row group / N&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;한 컬럼의 데이터가 연속으로&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Data Page&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1 - 10 MB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;압축/인코딩 단위&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Dictionary Page&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Column chunk 당 1개 (선택)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;값 -&gt; 정수 매핑&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Footer&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;파일 끝&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;schema + row group 위치 + 통계&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Footer 가 파일 끝에 있는 이유&lt;/strong&gt;: streaming write 를 지원하려면 파일을 다 쓴 뒤에야 전체 통계/위치를 알 수 있음. 대신 read 시 seek 두 번 (끝으로 -&gt; footer 읽기 -&gt; 필요한 row group 위치로).&lt;/p&gt;
&lt;h2 id=&quot;인코딩-encoding&quot;&gt;인코딩 (Encoding)&lt;/h2&gt;
&lt;p&gt;압축 전 값을 정수/오프셋으로 표현하는 단계. 컬럼 특성에 따라 자동 선택.&lt;/p&gt;















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;Encoding&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;적용 타입&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;최적 케이스&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;압축비&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;PLAIN&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;모든 타입&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;fallback, 무압축&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;RLE_DICTIONARY&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;모든 타입 (일반적)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮은 카디널리티 (성별, 국가)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10-100x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DELTA_BINARY_PACKED&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;INT32/INT64&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정렬/순차 정수 (id, timestamp)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;5-20x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DELTA_LENGTH_BYTE_ARRAY&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;문자열 길이 varying&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;3-10x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DELTA_BYTE_ARRAY&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정렬된 문자열&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;5-15x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;BYTE_STREAM_SPLIT&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FLOAT/DOUBLE&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;부동소수점 (뒤 codec 과 조합 개선)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;압축 개선&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Dictionary encoding 이 기본&lt;/em&gt;. 카디널리티가 임계값을 넘으면 PLAIN 으로 fallback.&lt;/p&gt;
&lt;h2 id=&quot;압축-compression-codec&quot;&gt;압축 (Compression Codec)&lt;/h2&gt;
&lt;p&gt;인코딩된 페이지를 물리적으로 압축. 인코딩 위에 codec 을 한 번 더 적용.&lt;/p&gt;





























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;Codec&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;압축비&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;압축 속도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;해제 속도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;권장&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;SNAPPY&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;2-4x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;옛 기본값, 균형형&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ZSTD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;3-6x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;em&gt;현대 기본값 권장&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;GZIP&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4-8x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최대 압축 필요 시&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;LZ4&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;2-3x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최고&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최고&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실시간 스트리밍&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;BROTLI&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;5-10x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;아카이빙 (드묾)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;LZO&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;2-4x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Legacy (사실상 대체됨)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;UNCOMPRESSED&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;디버깅만&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;ZSTD 가 현대 기본값&lt;/strong&gt;. SNAPPY 보다 압축비가 좋고 GZIP 보다 빠름. 새 파일은 ZSTD 로 시작.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;통계-statistics--predicate-pushdown&quot;&gt;통계 (Statistics) &amp;#x26; Predicate Pushdown&lt;/h2&gt;
&lt;p&gt;각 row group / column chunk / page 는 &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;null_count&lt;/code&gt; 통계를 저장. Reader 는 이 통계만 보고 &lt;em&gt;데이터를 읽지 않고 스킵&lt;/em&gt; 가능.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Query: SELECT * FROM t WHERE order_date &gt;= &apos;2026-01-01&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Row Group 1: min=2025-01-01, max=2025-12-31  →  skip (max &amp;#x3C; filter)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Row Group 2: min=2026-01-01, max=2026-06-30  →  read&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Row Group 3: min=2026-07-01, max=2026-12-31  →  read&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Bloom Filter&lt;/strong&gt; (선택): 컬럼 값의 hash 집합. &lt;code&gt;WHERE user_id = 12345&lt;/code&gt; 처럼 등호 조건에서 row group 을 확률적으로 스킵. 크기 ~1-2% 오버헤드.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Page Index&lt;/strong&gt; (Parquet 2.5+): row group 안의 페이지 수준 min/max 를 별도로 저장. 페이지 단위 스킵.&lt;/p&gt;
&lt;h2 id=&quot;스키마-진화-schema-evolution&quot;&gt;스키마 진화 (Schema Evolution)&lt;/h2&gt;
&lt;p&gt;Parquet 은 다음을 지원:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;컬럼 추가&lt;/strong&gt;: 새 컬럼 (기본값 or NULL)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컬럼 제거&lt;/strong&gt;: reader 무시&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컬럼 이름 변경&lt;/strong&gt;: 메타 수정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;타입 승격&lt;/strong&gt;: INT32 -&gt; INT64, FLOAT -&gt; DOUBLE&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중첩 구조 변경&lt;/strong&gt;: struct 필드 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;주의&lt;/strong&gt;: 타입 강등 (INT64 -&gt; INT32) 은 안전하지 않음. 오래된 파일과 새 스키마가 섞이면 reader 마다 처리 다름.&lt;/p&gt;
&lt;p&gt;트랜잭션 스키마 진화가 필요하면 &lt;em&gt;Iceberg / Delta Lake / Hudi&lt;/em&gt; 같은 table format 층을 위에 얹음.&lt;/p&gt;
&lt;h2 id=&quot;논리-타입-logical-types-parquet-2x&quot;&gt;논리 타입 (Logical Types, Parquet 2.x)&lt;/h2&gt;
&lt;p&gt;물리 타입 (INT32, INT64, BYTE_ARRAY 등) 위에 의미를 부여:&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;Logical Type&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;물리 타입&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;의미&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;STRING&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;UTF-8 문자열&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;DATE&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;INT32&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;epoch 이후 일수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;TIMESTAMP&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;INT64&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;밀리/마이크로/나노초&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;DECIMAL(p,s)&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;INT32/64/FIXED/BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;고정소수점&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;UUID&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FIXED_LEN_BYTE_ARRAY(16)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;128비트 UUID&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;JSON&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JSON 문자열&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;VARIANT&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;(nested)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;반정형 데이터 (Parquet 2.11+)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;GEOMETRY/GEOGRAPHY&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BYTE_ARRAY&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;WKT/WKB (Parquet 2.11+)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;중첩-구조-nested-schema&quot;&gt;중첩 구조 (Nested Schema)&lt;/h2&gt;
&lt;p&gt;Dremel 의 핵심 기여: &lt;em&gt;임의 깊이의 중첩 구조를 컬럼형으로 저장&lt;/em&gt;. Struct, List, Map 을 각 leaf 컬럼별 (definition level, repetition level) 로 인코딩.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;schema: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  user: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    id: int64,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    tags: list&amp;#x3C;string&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    addresses: list&amp;#x3C;{city: string, zip: string}&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;물리 저장:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  user.id                    (INT64)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  user.tags.list.element     (STRING) + rep/def levels&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  user.addresses.list.city   (STRING) + rep/def levels&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  user.addresses.list.zip    (STRING) + rep/def levels&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reader 는 rep/def level 로 원래 nested 구조를 복원. JSON 을 flatten 하지 않고도 컬럼 프로젝션이 됨.&lt;/p&gt;
&lt;h2 id=&quot;row-group--page-크기-결정&quot;&gt;Row Group / Page 크기 결정&lt;/h2&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;파라미터&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;권장&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;범위&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;트레이드오프&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Row Group&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;256-512 MB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;128 MB - 1 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;크면 압축 좋음/random access 느림&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Page&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1-10 MB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;512 KB - 64 MB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;작으면 필터링 세밀/오버헤드 증가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Rows per Row Group&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1M-10M&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컬럼 폭에 따라&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;메모리 vs 압축&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;일반 권장&lt;/strong&gt;: 256 MB row group + SNAPPY/ZSTD + Dictionary encoding.&lt;/p&gt;
&lt;h2 id=&quot;parquet-vs-다른-포맷&quot;&gt;Parquet vs 다른 포맷&lt;/h2&gt;




































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;저장&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;압축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;쿼리 속도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;스키마 진화&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;중첩&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;주요 사용처&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Parquet&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Column&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;3-6x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;데이터 레이크, 분석&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ORC&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Column&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4-8x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Hive/Spark&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Avro&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;2-4x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최고&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;스트리밍 (Kafka)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;CSV&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1-2x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Legacy, 사람 읽기&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1-3x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;API, 반정형&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;JSONL/NDJSON&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1-3x&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;로그, 스트리밍&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;대략&lt;/strong&gt;: Parquet 은 CSV 대비 &lt;em&gt;크기 10-100배 감소&lt;/em&gt;, 분석 쿼리 &lt;em&gt;10-100배 빠름&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;라이브러리&quot;&gt;라이브러리&lt;/h2&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;언어/도구&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;라이브러리&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;pyarrow&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;C++ Arrow 백엔드, 권장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;pandas&lt;/code&gt; (v2.0+)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;내부적으로 pyarrow 사용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Python/Rust&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;polars&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 빠름, 최근 표준화&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;SQL (in-process)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;duckdb&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Parquet 을 SQL 로 바로&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;JVM&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;parquet-mr&lt;/code&gt;, Spark&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Hadoop 생태계&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;parquet-go&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Segment/InfluxData 활용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;arrow-rs&lt;/code&gt;, &lt;code&gt;parquet&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;zero-copy, 매우 빠름&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;실전-예제&quot;&gt;실전 예제&lt;/h2&gt;
&lt;h3 id=&quot;python-pyarrow&quot;&gt;Python (pyarrow)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pyarrow &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pa&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pyarrow.parquet &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pq&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 쓰기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;table &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pa.table({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;name&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;ts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: pa.array([&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1706000000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1706000001&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1706000002&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;], &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pa.timestamp(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;ms&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pq.write_table(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    table,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;out.parquet&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    compression&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;zstd&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    row_group_size&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1_000_000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    use_dictionary&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    write_statistics&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 읽기 (필요한 컬럼만 + 필터)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;table &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pq.read_table(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;out.parquet&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    columns&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;ts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    filters&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&gt;=&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)],   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# predicate pushdown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;duckdb-sql-로-바로&quot;&gt;DuckDB (SQL 로 바로)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Parquet 을 테이블처럼 쿼리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; COUNT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://bucket/data/**/*.parquet&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-01-01&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Parquet 으로 저장&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;COPY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FROM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; orders &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; year&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2026&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;TO&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;orders_2026.parquet&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (FORMAT &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;PARQUET&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;COMPRESSION&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ZSTD);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;spark--aws-glueglue&quot;&gt;Spark / [[aws-glue|Glue]]&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# read&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;df &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; spark.read.parquet(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://bucket/data/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;df.filter(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;year = 2026&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).select(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;amount&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).show()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# write with partitioning&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;df.write \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .mode(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;overwrite&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .partitionBy(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;year&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;month&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .option(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;compression&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;zstd&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .parquet(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://bucket/out/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;데이터-레이크에서의-파티셔닝-관용&quot;&gt;데이터 레이크에서의 파티셔닝 관용&lt;/h2&gt;
&lt;p&gt;디렉토리 구조로 파티션 표현 (Hive 스타일):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;s3://bucket/events/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── year=2026/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── month=01/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   ├── day=01/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   │   └── part-00000.parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   └── day=02/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── month=02/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[[aws-athena|Athena]] / [[aws-redshift-spectrum|Spectrum]] / Spark 는 &lt;code&gt;WHERE year=2026 AND month=01&lt;/code&gt; 을 만나면 그 폴더의 파일만 스캔. &lt;em&gt;파티션 프루닝&lt;/em&gt; = 비용/시간 절감의 핵심.&lt;/p&gt;
&lt;h2 id=&quot;small-files-problem&quot;&gt;Small Files Problem&lt;/h2&gt;
&lt;p&gt;파티션이 세분화되거나 스트리밍 flush 가 잦으면 파일이 작아짐 (KB ~ MB). 결과:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Row group 이 너무 작아 압축비 하락&lt;/li&gt;
&lt;li&gt;파일 open/close 오버헤드 폭증&lt;/li&gt;
&lt;li&gt;메타데이터 오버헤드 (파일당 footer)&lt;/li&gt;
&lt;li&gt;[[aws-s3|S3]] LIST/GET 요청 비용 증가&lt;/li&gt;
&lt;li&gt;쿼리 엔진의 파일 스캔 병렬화 손해&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;해결&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Compaction job&lt;/strong&gt;: 작은 파일을 주기적으로 256 MB+ 로 합침&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파티션 세분화 완화&lt;/strong&gt;: &lt;code&gt;day&lt;/code&gt; 대신 &lt;code&gt;month&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Iceberg / Delta Lake / Hudi&lt;/strong&gt;: 자동 compaction, snapshot&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[[aws-s3|S3]] Tables&lt;/strong&gt; (2024+): 관리형 compaction&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;INT96 timestamp&lt;/strong&gt; = Legacy (Impala 호환). 새 파일은 INT64 + &lt;code&gt;timestamp&lt;/code&gt; logical type 사용. INT96 은 나노초까지만 표현 못함 + 표준 X.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;row group 이 너무 큼&lt;/strong&gt; = OOM 위험, 스트리밍 flush 시 지연. 너무 작음 = 위 small files 문제. 256 MB 근처가 sweet spot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Dictionary encoding 이 fallback&lt;/strong&gt; 하면 조용히 압축비 붕괴. Column cardinality 를 확인. 필요하면 &lt;code&gt;dictionary_page_size_limit&lt;/code&gt; 조정.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;파일 rename/append 없다&lt;/strong&gt;. Parquet 은 immutable. 수정하려면 새 파일로 write + 옛 파일 삭제. Iceberg/Delta 가 이 위에 트랜잭션 semantics 를 얹음.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Schema 변경 후 옛 파일과 섞임&lt;/strong&gt; = reader 따라 결과 다름. 스키마 이력 관리 (Iceberg schema ID) 또는 partitioned by schema version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;UTF-8 아닌 문자열&lt;/strong&gt; 을 STRING 으로 저장 = reader 별 처리 다름. BINARY (bytes) 로 저장하고 앱 레벨에서 처리.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;압축 codec 미지정 = SNAPPY 기본&lt;/strong&gt; (라이브러리별). 새 파이프라인은 ZSTD 로 명시. GZIP 은 CPU 부담 크니 아카이빙에만.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - Parquet 의 주된 소비자&lt;/li&gt;
&lt;li&gt;[[etl|ETL / ELT]] - Parquet 을 생성/소비하는 파이프라인&lt;/li&gt;
&lt;li&gt;[[aws-s3|AWS S3]] - Parquet 저장의 표준 백엔드&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - S3 의 Parquet 을 SQL 로&lt;/li&gt;
&lt;li&gt;[[aws-redshift-spectrum|Redshift Spectrum]] - Redshift 에서 S3 Parquet 쿼리&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - Parquet 로 변환하는 Spark ETL&lt;/li&gt;
&lt;li&gt;[[aws-redshift|AWS Redshift]] - COPY 로 Parquet 로드&lt;/li&gt;
&lt;li&gt;[[aws-s3-glacier|S3 Glacier]] - Parquet 파일의 장기 아카이빙&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>parquet</category><category>columnar</category><category>file-format</category><category>storage</category><author>koa (김신건)</author></item><item><title>Athena 다중 포맷 쿼리: JSON, CSV, Parquet, Iceberg</title><link>https://shinkeonkim.com/wiki/data-engineering/athena-multi-format-query/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/athena-multi-format-query/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;[[aws-athena|Amazon Athena]] 는 하나의 SQL 인터페이스에서 &lt;em&gt;[[aws-s3|S3]] 에 저장된 여러 포맷의 데이터를 그대로 조회&lt;/em&gt; 할 수 있음. 각 포맷은 &lt;strong&gt;SerDe&lt;/strong&gt; (Serializer/Deserializer) 로 해석되며, 파일 종류별로 다른 문법과 성능 트레이드오프가 있음. 이 페이지는 실전에서 가장 자주 만나는 &lt;strong&gt;JSON, CSV, [[apache-parquet|Parquet]], Iceberg&lt;/strong&gt; 를 다중 포맷 관점에서 정리.&lt;/p&gt;
&lt;h2 id=&quot;지원-파일-포맷--serde-매핑&quot;&gt;지원 파일 포맷 &amp;#x26; SerDe 매핑&lt;/h2&gt;













































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;SerDe (기본)&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;스캔 비용 (상대)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;CSV / TSV&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;LazySimpleSerDe&lt;/code&gt;, &lt;code&gt;OpenCSVSerDe&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사람이 읽기 편함, 대용량 부적합&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;100 (기준)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;Hive JsonSerDe&lt;/code&gt;, &lt;code&gt;OpenX JsonSerDe&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;반정형, 유연&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~80&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[apache-parquet|Parquet]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브 (Trino)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컬럼형 + 압축&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1-10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ORC&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컬럼형 + 인덱스&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1-10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Avro&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;AvroSerDe&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;로우형 + 스키마&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~40&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Ion&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Amazon Ion&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~40&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;RegexSerDe&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;RegexSerDe&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;로그 파싱 (ALB, CloudFront, Apache)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Grok&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;GrokSerDe&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;로그 패턴 매칭&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Apache Iceberg&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브 (Parquet 기반)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID + Time travel&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1-10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Delta Lake&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브 (2024+)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1-10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Apache Hudi&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;네이티브&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Incremental&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1-10&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
스캔 비용 상대 지표는 &lt;strong&gt;CSV 대비 대략&lt;/strong&gt;. 실제로 Parquet + 컬럼 프로젝션 + 파티션 프루닝 조합은 CSV 대비 &lt;strong&gt;100-400배 저렴&lt;/strong&gt; 하기도.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;csv--tsv-쿼리&quot;&gt;CSV / TSV 쿼리&lt;/h2&gt;
&lt;h3 id=&quot;기본-lazysimpleserde&quot;&gt;기본 (LazySimpleSerDe)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;access_log_csv&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  timestamp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ip STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  method STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  status_code &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  bytes &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT DELIMITED&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  FIELDS TERMINATED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BY&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;,&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  LINES TERMINATED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BY&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;\n&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;STORED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; TEXTFILE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://logs/access/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;TBLPROPERTIES (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;skip.header.line.count&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 헤더 skip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;인용부호-있는-csv-opencsvserde&quot;&gt;인용부호 있는 CSV (OpenCSVSerDe)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customers_csv&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  address&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 콤마 포함 가능&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.apache.hadoop.hive.serde2.OpenCSVSerde&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WITH&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SERDEPROPERTIES (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;separatorChar&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;,&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;quoteChar&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&quot;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;escapeChar&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;\\&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/customers/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;&lt;code&gt;OpenCSVSerde&lt;/code&gt; 는 모든 컬럼을 STRING 으로 읽음&lt;/strong&gt;. 숫자 컬럼은 쿼리 시 &lt;code&gt;CAST()&lt;/code&gt; 필요. &lt;code&gt;LazySimpleSerDe&lt;/code&gt; 는 스키마 대로 타입 캐스팅.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;json-쿼리&quot;&gt;JSON 쿼리&lt;/h2&gt;
&lt;h3 id=&quot;json-데이터-예-line-delimited-json-ndjson&quot;&gt;JSON 데이터 예 (line-delimited JSON, NDJSON)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;user_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2026-07-30T15:00:00Z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;props&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;page&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/home&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;duration_ms&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;320&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;user_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;43&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;view&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,  &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2026-07-30T15:00:01Z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;props&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;page&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/products/1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;duration_ms&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5120&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;기본-hive-jsonserde&quot;&gt;기본 (Hive JsonSerDe)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ts      STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  props   STRUCT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;page&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: STRING, duration_ms: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INT&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.apache.hive.hcatalog.data.JsonSerDe&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/events/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;openx-jsonserde-더-유연&quot;&gt;OpenX JsonSerDe (더 유연)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_openx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ts      STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  props   MAP&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;STRING, STRING&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.openx.data.jsonserde.JsonSerDe&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WITH&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SERDEPROPERTIES (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;ignore.malformed.json&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;true&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,              &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 파싱 실패 row skip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;dots.in.keys&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;true&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,                       &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- &quot;user.id&quot; 같은 키 허용&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;case.insensitive&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;true&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,                   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 대소문자 무시&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;mapping.userid&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;user_id&apos;&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                   -- 원본 -&gt; 컬럼명 매핑&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/events/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;중첩-필드-접근&quot;&gt;중첩 필드 접근&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; user_id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;       event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       props&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; page&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       props&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;duration_ms&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; duration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; props&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;duration_ms&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;json_extract-serde-없이-raw-string&quot;&gt;JSON_EXTRACT (SerDe 없이 raw string)&lt;/h3&gt;
&lt;p&gt;컬럼을 STRING 으로 두고 필요할 때만 파싱:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  payload STRING&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/events/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; JSON_EXTRACT_SCALAR(payload, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;$.user_id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; user_id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;       JSON_EXTRACT_SCALAR(payload, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;$.props.page&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; page&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       CAST&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(JSON_EXTRACT_SCALAR(payload, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;$.props.duration_ms&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; INT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; duration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 스키마 진화 자유. &lt;strong&gt;단점&lt;/strong&gt;: 매번 파싱 (느림, 비쌈).&lt;/p&gt;
&lt;h3 id=&quot;array-unnest&quot;&gt;Array UNNEST&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;user_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;tags&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;premium&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;kr&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;beta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;users_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  tags    &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ARRAY&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;STRING&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.apache.hive.hcatalog.data.JsonSerDe&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/users/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- ARRAY 를 row 로 풀기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; u&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;user_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, tag&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;users_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; u, UNNEST(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;u&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;tags&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t(tag);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;중첩-array-of-struct&quot;&gt;중첩 ARRAY OF STRUCT&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;order_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;sku&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;qty&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}, {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;sku&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;qty&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}]}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  order_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  items    &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ARRAY&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;STRUCT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sku: STRING, qty: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INT&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.apache.hive.hcatalog.data.JsonSerDe&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://raw/orders/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- UNNEST + STRUCT 필드 접근&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;sku&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;qty&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; o, UNNEST(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t(item);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;apache-parquetparquet-쿼리&quot;&gt;[[apache-parquet|Parquet]] 쿼리&lt;/h2&gt;
&lt;h3 id=&quot;기본&quot;&gt;기본&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  order_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  amount &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;DECIMAL&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  order_ts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;PARTITIONED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; INT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;month&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; INT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;STORED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; PARQUET&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://curated/orders/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;TBLPROPERTIES (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;parquet.compression&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;ZSTD&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ALTER&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ADD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  PARTITION&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;year=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2026&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;month=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://curated/orders/year=2026/month=7/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;컬럼-프로젝션--파티션-프루닝&quot;&gt;컬럼 프로젝션 + 파티션 프루닝&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 스캔 = 필요한 컬럼 × 필요한 파티션&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; SUM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(amount)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; year&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2026&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AND&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; month&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 7&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 전체 스캔 (파티션 프루닝 실패)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; SUM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(amount) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; order_ts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-01&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
파티션 컬럼은 원본 그대로 (&lt;code&gt;year = 2026&lt;/code&gt;), 함수/캐스팅 wrap 금지. 자세히: [[aws-athena|Athena]] 함정 섹션.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;parquet-중첩-필드&quot;&gt;Parquet 중첩 필드&lt;/h3&gt;
&lt;p&gt;Parquet 은 중첩 struct/list 를 컬럼형으로 저장. SQL 은 JSON 과 동일:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;sku&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;qty&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders_nested&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; o, UNNEST(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t(item);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;apache-iceberg-쿼리&quot;&gt;Apache Iceberg 쿼리&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.orders (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  order_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  amount &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;DECIMAL&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  order_date &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;DATE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;PARTITIONED &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (order_date)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://lakehouse/orders/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;TBLPROPERTIES (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;table_type&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;ICEBERG&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;format&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;parquet&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;write_compression&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;zstd&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- ACID&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INSERT INTO&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; VALUES&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;00&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;DATE&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-30&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;UPDATE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; SET&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; amount &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;00&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; order_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;DELETE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; order_id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;MERGE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; INTO&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;USING&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; staging &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  ON&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  WHEN&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; MATCHED&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; THEN&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; UPDATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; SET&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; amount &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;amount&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  WHEN&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; NOT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; MATCHED&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; THEN&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; INSERT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; VALUES&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;user_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;amount&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_date&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Time travel&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FOR&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TIMESTAMP&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OF &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-01 00:00:00&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lakehouse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; FOR&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; VERSION&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OF &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12345&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세히: [[aws-athena|Athena]] Iceberg 섹션.&lt;/p&gt;
&lt;h2 id=&quot;다중-포맷-조인-같은-쿼리&quot;&gt;다중 포맷 조인 (같은 쿼리)&lt;/h2&gt;
&lt;p&gt;Athena 는 서로 다른 포맷의 테이블을 자유롭게 조인.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Parquet dimension&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  SUM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;amount&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; revenue  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Parquet fact&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; d    &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- Parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;JOIN&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;orders_json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; f      &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- JSON raw&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  ON&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_id&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;user_id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;purchase&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  AND&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;country&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;KR&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GROUP BY&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Athena 내부 (Trino) 가 각 SerDe 로 읽고 컬럼형으로 변환해 조인.&lt;/p&gt;
&lt;h2 id=&quot;ctas-포맷-변환&quot;&gt;CTAS: 포맷 변환&lt;/h2&gt;
&lt;p&gt;원본 CSV/JSON 을 [[apache-parquet|Parquet]] 로 승격.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.events_parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WITH&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  format &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;PARQUET&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  parquet_compression &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;ZSTD&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  external_location &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://curated/events/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  partitioned_by &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ARRAY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&apos;year&apos;, &apos;month&apos;, &apos;day&apos;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  user_id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  CAST&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(from_iso8601_timestamp(ts) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TIMESTAMP&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; event_ts,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  props&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  props&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;duration_ms&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  YEAR&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(from_iso8601_timestamp(ts)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; year&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  MONTH&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(from_iso8601_timestamp(ts)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; month&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  DAY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(from_iso8601_timestamp(ts)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AS&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; day&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; from_iso8601_timestamp(ts) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TIMESTAMP&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-01&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;결과&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원본 JSON 대비 5-10 배 압축&lt;/li&gt;
&lt;li&gt;컬럼 프루닝 가능&lt;/li&gt;
&lt;li&gt;파티션 프루닝 가능&lt;/li&gt;
&lt;li&gt;이후 쿼리 요금 대폭 절감&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;주의&lt;/strong&gt;: CTAS 는 한 번에 최대 100 파티션. 대량이면 &lt;code&gt;INSERT INTO ... SELECT&lt;/code&gt; 로 청크 분할.&lt;/p&gt;
&lt;h2 id=&quot;insert-into-증분-적재&quot;&gt;INSERT INTO (증분 적재)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INSERT INTO&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; curated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;events_json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WHERE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; from_iso8601_timestamp(ts) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; DATE&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-30&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  AND&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; from_iso8601_timestamp(ts) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; DATE&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;2026-07-31&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Iceberg 이면 트랜잭션 with duplicate protection 도 가능 (MERGE).&lt;/p&gt;
&lt;h2 id=&quot;로그-파싱-regexserde&quot;&gt;로그 파싱 (RegexSerDe)&lt;/h2&gt;
&lt;p&gt;ALB/CloudFront/S3 access log 처럼 정해진 텍스트 로그:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;CREATE&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; EXTERNAL&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; TABLE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; raw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;alb_logs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  time&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  elb STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  client_ip STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  target&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  request_processing_time DOUBLE,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  target_processing_time DOUBLE,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  response_processing_time DOUBLE,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  elb_status_code STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  target_status_code STRING,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  received_bytes &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  sent_bytes &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;BIGINT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  request STRING&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ROW&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; FORMAT SERDE &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;org.apache.hadoop.hive.serde2.RegexSerDe&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WITH&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SERDEPROPERTIES (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;serialization.format&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;1&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &apos;input.regex&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \&quot;([^ ]*) (.*)\&quot; ...&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;LOCATION&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s3://alb-logs/AWSLogs/123/elasticloadbalancing/us-east-1/2026/07/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Athena 콘솔 안에 ALB / CloudFront / VPC Flow Logs 등 정형 CREATE TABLE snippet 이 있음.&lt;/p&gt;
&lt;h2 id=&quot;파일-포맷-선택-가이드&quot;&gt;파일 포맷 선택 가이드&lt;/h2&gt;





































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;시나리오&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;원본 이벤트 스트림 raw 저장&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JSON (스키마 진화 유연)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;로그 원본 (외부 제공)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;그대로 (Parquet 변환 검토)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;정제 후 분석&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[apache-parquet|Parquet]] + ZSTD + partition&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ACID 트랜잭션 필요&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Iceberg / Delta&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;사람이 읽기 필요&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CSV (임시), 아니면 Parquet + BI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;사이즈 최적화&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Parquet + ZSTD (또는 GZIP)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ML 학습 tensor&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Parquet&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;스캔-비용-실제-동일-데이터-다른-포맷&quot;&gt;스캔 비용 실제 (동일 데이터, 다른 포맷)&lt;/h2&gt;
&lt;p&gt;원본 4 TB 로그 (uncompressed CSV, 100 컬럼) 를 컬럼 하나만 쿼리:&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;스캔량&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;비용 (Athena $5/TB)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;CSV (uncompressed)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4 TB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$20&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;CSV + GZIP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1.3 TB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$6.50&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;JSON (unc.)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~3.2 TB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Parquet (SNAPPY, 100 컬럼 -&gt; 1 컬럼 프로젝션)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~10 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$0.05&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Parquet (ZSTD, 프로젝션 + 파티션 프루닝 90%)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;$0.005&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;즉 &lt;strong&gt;Parquet + partition + projection 조합은 CSV 대비 4000 배&lt;/strong&gt; 저렴.&lt;/p&gt;
&lt;h2 id=&quot;스키마-진화-다루기&quot;&gt;스키마 진화 다루기&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenX SerDe + &lt;code&gt;ignore.malformed.json=true&lt;/code&gt; 로 새 필드 자동 무시&lt;/li&gt;
&lt;li&gt;새 컬럼 추가 시 &lt;code&gt;ALTER TABLE ADD COLUMNS&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Parquet&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;새 컬럼 추가 -&gt; 옛 파일은 NULL 반환&lt;/li&gt;
&lt;li&gt;컬럼 타입 변경은 안전하지 않음 (Iceberg 로 승격 검토)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Iceberg&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Schema evolution 이 first-class. 컬럼 추가/제거/이름 변경/타입 승격 모두 트랜잭션.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;&lt;code&gt;SELECT *&lt;/code&gt; 로 JSON/CSV&lt;/strong&gt; = 전체 컬럼 파싱, 비용 폭탄. 필요 컬럼만 SELECT.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;OpenCSVSerDe 는 모두 STRING&lt;/strong&gt;. 숫자/날짜 컬럼은 쿼리마다 CAST -&gt; 느림. LazySimpleSerDe 로 스키마 지정 또는 [[apache-parquet|Parquet]] 로 승격.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;파티션 컬럼에 함수 적용&lt;/strong&gt; = 파티션 프루닝 실패. &lt;code&gt;WHERE year = 2026&lt;/code&gt; 그대로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;JSON 중첩 필드 SerDe 매핑&lt;/strong&gt;. Hive JsonSerDe 는 대소문자 민감, OpenX 는 옵션. 소스 케이스 맞춰 SerDe 선택.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;작은 파일 수천 개&lt;/strong&gt; = 성능/비용 폭탄. CTAS 로 정기 compaction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;&lt;code&gt;JSON_EXTRACT&lt;/code&gt; 남용&lt;/strong&gt; = 매 쿼리 파싱. 자주 쓰는 필드는 SerDe 로 매핑 또는 Parquet 로 승격.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Iceberg 를 Lake Formation 으로 등록&lt;/strong&gt; = DDL 제한. Athena 에서 UPDATE/DELETE 안 되는 경우.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;CTAS 한 번에 100 파티션 초과&lt;/strong&gt; = 오류. &lt;code&gt;INSERT INTO ... SELECT&lt;/code&gt; 로 나눠서.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - 상위 서비스&lt;/li&gt;
&lt;li&gt;[[apache-parquet|Apache Parquet]] - 권장 포맷&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - Catalog + Crawler&lt;/li&gt;
&lt;li&gt;[[aws-s3|S3]] - 데이터 저장&lt;/li&gt;
&lt;li&gt;[[data-lake|Data Lake]] - 다중 포맷 저장의 근본&lt;/li&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - 정제 후 소비&lt;/li&gt;
&lt;li&gt;[[aws-lake-formation|Lake Formation]] - 세분화 권한&lt;/li&gt;
&lt;li&gt;[[etl|ETL / ELT]] - CTAS 파이프라인&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>aws</category><category>athena</category><category>data-engineering</category><category>json</category><category>parquet</category><category>serde</category><category>iceberg</category><author>koa (김신건)</author></item><item><title>ETL / ELT</title><link>https://shinkeonkim.com/wiki/data-engineering/etl/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/etl/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ETL&lt;/strong&gt; = &lt;strong&gt;Extract&lt;/strong&gt; (추출) + &lt;strong&gt;Transform&lt;/strong&gt; (변환) + &lt;strong&gt;Load&lt;/strong&gt; (적재). 여러 소스에서 데이터를 뽑아 정제한 뒤 [[data-warehouse|데이터 웨어하우스]] 에 저장하는 파이프라인.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ELT&lt;/strong&gt; 는 순서를 바꿔서 원본 그대로 warehouse 에 먼저 적재하고, warehouse SQL 로 변환. 현대 클라우드 DW ([[aws-redshift|Redshift]], BigQuery, Snowflake) 의 컴퓨트가 강력해지면서 사실상 표준이 됨.&lt;/p&gt;
&lt;h2 id=&quot;3단계&quot;&gt;3단계&lt;/h2&gt;
&lt;h3 id=&quot;1-extract-추출&quot;&gt;1. Extract (추출)&lt;/h3&gt;
&lt;p&gt;소스 시스템에서 데이터 읽기.&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;소스 유형&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;예시&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;추출 방식&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;관계형 DB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[postgresql|Postgres]], MySQL, [[aws-rds|RDS]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JDBC full/incremental, CDC (WAL/binlog)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;NoSQL&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[dynamodb|DynamoDB]], [[mongodb|MongoDB]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Streams, snapshot&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;SaaS API&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Salesforce, Stripe, Zendesk&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;REST API + pagination&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;파일&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CSV, JSON, [[apache-parquet|Parquet]] on [[aws-s3|S3]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Object listing + read&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;이벤트 스트림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Kafka, Kinesis&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Consumer group&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;로그&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Application logs&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Fluent Bit, CloudWatch subscription&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;추출 방식&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: 매번 전체 (작은 테이블)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incremental (updated_at)&lt;/strong&gt;: &lt;code&gt;WHERE updated_at &gt; last_run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CDC (Change Data Capture)&lt;/strong&gt;: WAL/binlog 스트림 -&gt; 거의 실시간&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snapshot + delta&lt;/strong&gt;: 주기적 full + 그 사이 CDC&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-transform-변환&quot;&gt;2. Transform (변환)&lt;/h3&gt;
&lt;p&gt;원본을 사용 가능한 형태로 정제.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cleaning&lt;/strong&gt;: null 처리, 이상치 제거, dedup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type casting&lt;/strong&gt;: 문자열 -&gt; DATE/NUMERIC 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standardization&lt;/strong&gt;: timezone UTC, currency, unit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enrichment&lt;/strong&gt;: 다른 소스 join, geolocation lookup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aggregation&lt;/strong&gt;: hourly/daily rollup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Denormalization&lt;/strong&gt;: [[data-warehouse|DW]] star schema 형태로 flatten&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anonymization&lt;/strong&gt;: PII 마스킹, hashing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-load-적재&quot;&gt;3. Load (적재)&lt;/h3&gt;
&lt;p&gt;Target 시스템 (DW, 데이터 마트, 검색 인덱스, 특징 저장소) 에 씀.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bulk COPY&lt;/strong&gt;: [[aws-redshift|Redshift]] &lt;code&gt;COPY&lt;/code&gt;, Snowflake &lt;code&gt;COPY INTO&lt;/code&gt;, BigQuery &lt;code&gt;LOAD DATA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upsert (MERGE)&lt;/strong&gt;: SCD 관리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Append-only&lt;/strong&gt;: 이벤트 로그, immutable fact&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overwrite partition&lt;/strong&gt;: 하루치 재처리 시 파티션 단위 삭제 후 재적재&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;etl-vs-elt&quot;&gt;ETL vs ELT&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph ETL_flow[전통 ETL]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S1[Source] --&gt; E1[Extract]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E1 --&gt; T1[&quot;Transform&amp;#x3C;br/&gt;(별도 ETL 서버)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        T1 --&gt; L1[&quot;Load into DW&amp;#x3C;br/&gt;(정제된 형태)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph ELT_flow[현대 ELT]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S2[Source] --&gt; E2[Extract]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E2 --&gt; L2[&quot;Load raw into DW&amp;#x3C;br/&gt;(원본 그대로)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        L2 --&gt; T2[&quot;Transform&amp;#x3C;br/&gt;(DW SQL 로)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;ETL&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;ELT&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;변환 위치&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;별도 ETL 서버/엔진&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DW 내부 SQL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DW 저장 데이터&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정제된 최종본&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Raw + staging + 최종본&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;재처리&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;파이프라인 다시 실행 (느림)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SQL 로 rebuild (빠름)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;스키마 유연성&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사전 스키마 필요&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Schema-on-read 가능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DW 비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;저장 적음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;저장 많음 (raw 유지)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;컴퓨트 비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ETL 서버 (별도)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DW 컴퓨트 사용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;툴&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Informatica, Talend, SSIS, [[aws-glue|Glue]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;dbt, Dataform, [[aws-redshift|Redshift]] SQL, Snowflake&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;적합&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소스 데이터가 크고 DW 컴퓨트가 비쌀 때&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;클라우드 DW (탄력적 컴퓨트)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;디버깅&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여러 시스템 걸침, 어려움&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DW 안에서 SQL, 쉬움&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;현대 표준&lt;/strong&gt;: 클라우드 DW + dbt + Airflow/Dagster/Prefect. ELT 방향으로 옮겨감.&lt;/p&gt;
&lt;h3 id=&quot;언제-etl-이-여전히-맞나&quot;&gt;언제 ETL 이 여전히 맞나&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PII 를 DW 에 저장하면 안 될 때&lt;/strong&gt; -&gt; 로드 전 마스킹&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;소스 볼륨이 DW 저장/컴퓨트 대비 압도적으로 클 때&lt;/strong&gt; -&gt; 미리 aggregate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DW 가 legacy on-prem 이고 확장이 어려울 때&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;아키텍처-패턴&quot;&gt;아키텍처 패턴&lt;/h2&gt;
&lt;h3 id=&quot;배치-파이프라인&quot;&gt;배치 파이프라인&lt;/h3&gt;
&lt;p&gt;가장 흔함. 시간/일 단위.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Src[Source DB] --&gt;|&quot;nightly dump&quot;| Raw[&quot;S3 raw/&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Raw --&gt;|&quot;[[aws-glue|Glue]] job&quot;| Staged[&quot;S3 staged/&amp;#x3C;br/&gt;[[apache-parquet|Parquet]]&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Staged --&gt;|&quot;COPY&quot;| DW[&quot;[[aws-redshift|Redshift]]&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DW --&gt;|&quot;dbt run&quot;| Marts[&quot;Marts&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Airflow[Airflow scheduler] -.orchestrate.-&gt; Raw&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Airflow -.orchestrate.-&gt; Staged&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Airflow -.orchestrate.-&gt; DW&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;오케스트레이터&lt;/strong&gt;: Airflow, Dagster, Prefect, [[aws-step-functions|Step Functions]], Argo Workflows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실행 엔진&lt;/strong&gt;: Spark ([[aws-glue|Glue]]), Python, dbt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;저장&lt;/strong&gt;: [[aws-s3|S3]] raw -&gt; [[apache-parquet|Parquet]] staged -&gt; [[aws-redshift|Redshift]] marts&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;스트리밍-파이프라인&quot;&gt;스트리밍 파이프라인&lt;/h3&gt;
&lt;p&gt;거의 실시간 (초/분 단위).&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    App[App 이벤트] --&gt; Kafka[Kafka / Kinesis]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Kafka --&gt; Flink[&quot;Flink / Kafka Streams&amp;#x3C;br/&gt;(변환/집계)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Flink --&gt; DW[&quot;[[aws-redshift|Redshift]] Streaming Ingestion&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Flink --&gt; S3[&quot;S3 (이벤트 원본 보관)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    S3 --&gt; Batch[&quot;배치 재처리&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;엔진&lt;/strong&gt;: Apache Flink, Spark Structured Streaming, Kafka Streams, ksqlDB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;딜리버리&lt;/strong&gt;: exactly-once (Flink checkpoints, Kafka transactions)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이슈&lt;/strong&gt;: late-arriving events, watermark, event time vs processing time&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;lambda--kappa&quot;&gt;Lambda / Kappa&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lambda&lt;/strong&gt;: 실시간 (speed) + 배치 (batch) 이중 파이프라인. 배치가 최종 진실.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kappa&lt;/strong&gt;: 스트리밍 only. 재처리도 스트림 재실행.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현대는 Kappa 지향 (하나의 파이프라인).&lt;/p&gt;
&lt;h3 id=&quot;cdc-파이프라인&quot;&gt;CDC 파이프라인&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Source DB WAL/binlog] -&gt; Debezium -&gt; Kafka -&gt; Sink (DW / lake / cache)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;소스 스키마 변경 -&gt; 자동 propagation (설정에 따라)&lt;/li&gt;
&lt;li&gt;Sub-second 지연&lt;/li&gt;
&lt;li&gt;[[aws-redshift|Redshift]] Zero-ETL, DMS, Fivetran 등 매니지드 옵션&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;medallion-architecture-bronze--silver--gold&quot;&gt;Medallion Architecture (Bronze / Silver / Gold)&lt;/h3&gt;
&lt;p&gt;Databricks 가 대중화한 [[data-warehouse|Lakehouse]] 계층:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bronze&lt;/strong&gt;: raw ingestion, 소스 형식 유지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Silver&lt;/strong&gt;: cleaned, deduped, enriched, join 가능한 상태&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gold&lt;/strong&gt;: business-level aggregates, BI 소비&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kimball 의 staging / core / mart 와 사실상 같은 개념.&lt;/p&gt;
&lt;h2 id=&quot;오케스트레이션-도구&quot;&gt;오케스트레이션 도구&lt;/h2&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;도구&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Apache Airflow&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Python DAG, 사실상 표준, 규모 크면 세팅 복잡&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Dagster&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자산 (asset) 중심, 강한 타입, dbt 통합 우수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Prefect&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Pythonic, 동적 워크플로우, 서버리스 옵션&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-step-functions|AWS Step Functions]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버리스, AWS 네이티브, 상태 머신&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-glue|AWS Glue]] Workflows&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Glue 내장, 단순&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Argo Workflows&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Kubernetes 네이티브&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Kestra&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;YAML 선언형, 최근 성장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;cron + Bash&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;초기 프로토타입만&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;변환-도구&quot;&gt;변환 도구&lt;/h2&gt;
&lt;h3 id=&quot;dbt-data-build-tool&quot;&gt;dbt (data build tool)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;ELT 의 T&lt;/em&gt;. SQL SELECT 문 + Jinja 로 변환 로직을 버전 관리.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- models/marts/fact_orders.sql&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{{ config(materialized&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;incremental&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, unique_key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;order_id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;order_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;amount&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;created_at&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {{ ref(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;stg_orders&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) }} o&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{% &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; is_incremental() %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  WHERE&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; o&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;updated_at&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; MAX&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(updated_at) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {{ this }})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{% endif %}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;테스트 (unique, not null, accepted values) 코드로&lt;/li&gt;
&lt;li&gt;Lineage 자동 문서화 (&lt;code&gt;dbt docs&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;사실상 표준&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;spark-aws-glueglue-databricks-emr&quot;&gt;Spark ([[aws-glue|Glue]], Databricks, EMR)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;큰 변환&lt;/em&gt;, semi-structured, ML 특징 엔지니어링.&lt;/p&gt;
&lt;h3 id=&quot;pandas--pandaspandas--polars--duckdb&quot;&gt;Pandas / [[pandas|pandas]] / Polars / DuckDB&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;작은 배치&lt;/em&gt;, 노트북, 프로토타입.&lt;/p&gt;
&lt;h2 id=&quot;데이터-계약-data-contracts&quot;&gt;데이터 계약 (Data Contracts)&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;소스 -&gt; 파이프라인&lt;/em&gt; 사이 스키마/의미 합의. 소스 팀이 스키마를 몰래 바꿔서 파이프라인이 조용히 깨지는 사고를 방지.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 예: user_signup 이벤트 계약&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;user_signup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;owner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;growth-team&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;schema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  user_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;uuid&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  email&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;string, PII&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  signup_at&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;timestamp, utc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  source&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;enum[web, ios, android]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;sla&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  freshness&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;5min&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  completeness&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;99.9%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Protobuf/Avro/JSON Schema 로 코드화&lt;/li&gt;
&lt;li&gt;CI 에서 소스 릴리즈 시 계약 검증&lt;/li&gt;
&lt;li&gt;위반 시 배포 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;idempotency--reprocessing&quot;&gt;Idempotency &amp;#x26; Reprocessing&lt;/h2&gt;
&lt;p&gt;파이프라인은 &lt;em&gt;같은 입력 -&gt; 같은 출력&lt;/em&gt; 이어야 안전한 재실행이 가능.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;핵심 기법&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;파티션 재작성&lt;/strong&gt; (&lt;code&gt;INSERT OVERWRITE&lt;/code&gt; 하루치)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자연 키 기반 upsert&lt;/strong&gt; (&lt;code&gt;MERGE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Watermark&lt;/strong&gt; (스트리밍 late-arriving)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DAG 실행 ID&lt;/strong&gt; 로 stale write 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Anti-pattern&lt;/strong&gt;: &lt;code&gt;INSERT ... SELECT&lt;/code&gt; 를 재실행 -&gt; 중복 축적.&lt;/p&gt;
&lt;h2 id=&quot;데이터-품질-data-quality&quot;&gt;데이터 품질 (Data Quality)&lt;/h2&gt;
&lt;p&gt;파이프라인의 실질적 신뢰도.&lt;/p&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;검증 종류&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;예시&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Schema&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컬럼 타입/개수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Not null&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;필수 컬럼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Unique&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;기본 키&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Referential&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;fact -&gt; dim FK&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Range&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;나이 0-150, 금액 &gt;= 0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Freshness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;마지막 update 가 SLA 내&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Completeness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;row 수 이전 배치 대비 -50% 이면 alert&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Distribution drift&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;값 분포가 급변하면 alert&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;도구&lt;/strong&gt;: dbt tests, Great Expectations, Soda, Monte Carlo, Bigeye.&lt;/p&gt;
&lt;h2 id=&quot;관측성-data-observability&quot;&gt;관측성 (Data Observability)&lt;/h2&gt;
&lt;p&gt;파이프라인의 5가지 축:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Freshness&lt;/strong&gt; - 마지막 갱신 시점&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Volume&lt;/strong&gt; - row 수&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schema&lt;/strong&gt; - 스키마 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distribution&lt;/strong&gt; - 값 분포&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lineage&lt;/strong&gt; - upstream/downstream 영향 범위&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;aws-에서의-etl-구성&quot;&gt;AWS 에서의 ETL 구성&lt;/h2&gt;





































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;컴포넌트&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;선택지&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Extract&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|Glue]] Crawler, DMS (CDC), Kinesis Firehose&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Store&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-s3|S3]] (data lake), [[apache-parquet|Parquet]] 권장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Transform&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|Glue]] Spark job, [[aws-athena|Athena]] CTAS, [[aws-lambda|Lambda]] (소규모), dbt on Redshift&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Load / Query&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-redshift|Redshift]] COPY, [[aws-athena|Athena]] on S3, [[aws-redshift-spectrum|Spectrum]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Orchestrate&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-step-functions|Step Functions]], MWAA (managed Airflow), EventBridge Scheduler&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Catalog&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|Glue]] Data Catalog&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Quality&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|Glue]] Data Quality (DQDL), Deequ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;한 파이프라인에 모든 로직 몰아넣기&lt;/strong&gt; = 재사용 불가. Extract, Transform, Load 를 태스크 단위로 분리하고 재시도/재실행이 각각 가능해야 함.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;파이프라인 실패를 조용히 넘김&lt;/strong&gt; = 다운스트림이 stale 데이터로 오판. Freshness alert + SLA 필수.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;소스 스키마 변경 감지 안 함&lt;/strong&gt; = 컬럼 추가/제거/타입 변경 시 파이프라인이 오늘부터 다른 데이터를 만듬. 데이터 계약 + schema evolution 정책 필수.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;재실행 불가능한 파이프라인&lt;/strong&gt; = 프로덕션 사고. &lt;code&gt;INSERT ... SELECT&lt;/code&gt; 대신 &lt;code&gt;INSERT OVERWRITE PARTITION&lt;/code&gt; 또는 &lt;code&gt;MERGE&lt;/code&gt; 로 idempotent 하게 설계.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;작은 파일 수천 개 생성&lt;/strong&gt; = [[apache-parquet|Parquet]] 성능 붕괴 + [[aws-athena|Athena]] / [[aws-redshift-spectrum|Spectrum]] 비용 폭탄. Compact job 필수 (128 MB - 1 GB 파일 크기 target).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;PII 를 raw 로 DW 에 로드&lt;/strong&gt; = 규제 위반. 로드 전 masking / tokenization, 또는 정책 기반 컬럼 접근 제어.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Airflow 의 &lt;code&gt;execution_date&lt;/code&gt; 혼동&lt;/strong&gt; = “실행 시각” 이 아니라 “이 실행이 처리하는 논리 시각” (interval start). 미리 알아두지 않으면 하루 어긋난 데이터가 나옴.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - ETL 의 target&lt;/li&gt;
&lt;li&gt;[[apache-parquet|Apache Parquet]] - 중간/최종 저장 포맷&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - AWS 관리형 ETL&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - S3 데이터 SQL 쿼리&lt;/li&gt;
&lt;li&gt;[[aws-redshift|AWS Redshift]] - AWS 관리형 DW&lt;/li&gt;
&lt;li&gt;[[aws-redshift-spectrum|Redshift Spectrum]] - S3 직접 쿼리&lt;/li&gt;
&lt;li&gt;[[aws-s3|AWS S3]] - Data lake 저장소&lt;/li&gt;
&lt;li&gt;[[aws-s3-glacier|S3 Glacier]] - 원본 장기 보관&lt;/li&gt;
&lt;li&gt;[[aws-lambda|AWS Lambda]] - 이벤트 기반 소규모 변환&lt;/li&gt;
&lt;li&gt;[[aws-step-functions|AWS Step Functions]] - 서버리스 오케스트레이션&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>etl</category><category>elt</category><category>data-pipeline</category><category>ingestion</category><author>koa (김신건)</author></item><item><title>Hadoop / Spark</title><link>https://shinkeonkim.com/wiki/data-engineering/hadoop-spark/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/hadoop-spark/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Hadoop&lt;/strong&gt; 은 &lt;em&gt;2006 야후에서 시작된 분산 저장 + 분산 처리 오픈소스 플랫폼&lt;/em&gt;. Google 이 2003-2004 년에 발표한 &lt;strong&gt;GFS&lt;/strong&gt; (분산 파일시스템) 와 &lt;strong&gt;MapReduce&lt;/strong&gt; (분산 처리 모델) 논문을 오픈소스로 구현한 것이 출발점.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spark&lt;/strong&gt; 는 &lt;em&gt;2009 UC Berkeley AMPLab 에서 시작된 인메모리 분산 처리 엔진&lt;/em&gt;. MapReduce 의 디스크 I/O 병목을 해결하기 위해 &lt;strong&gt;RDD&lt;/strong&gt; (Resilient Distributed Dataset) 개념을 도입해 반복 계산에서 &lt;strong&gt;10-100 배 빠른 성능&lt;/strong&gt; 을 제공.&lt;/p&gt;
&lt;p&gt;두 시스템 모두 &lt;em&gt;단일 서버로 처리 불가능한 규모의 데이터&lt;/em&gt; 를 여러 서버로 나눠 처리하는 것이 목적. 오늘날 [[data-lake|데이터 레이크]] / [[data-warehouse|데이터 웨어하우스]] 위의 대규모 처리 엔진은 대부분 이 두 계보를 잇는다.&lt;/p&gt;
&lt;h2 id=&quot;hadoop-의-두-축&quot;&gt;Hadoop 의 두 축&lt;/h2&gt;
&lt;p&gt;Hadoop 은 원래 &lt;strong&gt;저장 (HDFS)&lt;/strong&gt; + &lt;strong&gt;처리 (MapReduce)&lt;/strong&gt; 두 컴포넌트로 시작. 이후 &lt;strong&gt;YARN&lt;/strong&gt; (자원 관리) 이 분리되어 3 요소가 됨.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Hadoop&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph Storage[&quot;저장&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            HDFS[&quot;HDFS&amp;#x3C;br/&gt;(분산 파일시스템)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph Resource[&quot;자원 관리&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            YARN[&quot;YARN&amp;#x3C;br/&gt;(스케줄러)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph Compute[&quot;처리&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            MR[&quot;MapReduce&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            OtherEngines[&quot;Spark, Hive, Flink, Tez...&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Compute --&gt; YARN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Compute --&gt; HDFS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    YARN --&gt; Storage&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;hdfs-hadoop-distributed-file-system&quot;&gt;HDFS (Hadoop Distributed File System)&lt;/h3&gt;
&lt;p&gt;파일을 &lt;strong&gt;고정 크기 블록&lt;/strong&gt; (기본 128 MB) 으로 나눠 여러 노드에 분산 저장 + 복제.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    NN[&quot;NameNode&amp;#x3C;br/&gt;(메타데이터: 파일→블록→노드 매핑)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DN1[&quot;DataNode 1&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DN2[&quot;DataNode 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DN3[&quot;DataNode 3&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DN4[&quot;DataNode 4&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    NN -.-&gt;|heartbeat| DN1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    NN -.-&gt;|heartbeat| DN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    NN -.-&gt;|heartbeat| DN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    NN -.-&gt;|heartbeat| DN4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File[&quot;file.parquet 1 GB&quot;] --&gt; B1[&quot;Block 1 (128MB)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; B2[&quot;Block 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; B3[&quot;Block 3&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    File --&gt; B8[&quot;... Block 8&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B1 -.-&gt;|&quot;replica 3&quot;| DN1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B1 -.-&gt; DN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B1 -.-&gt; DN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B2 -.-&gt; DN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B2 -.-&gt; DN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    B2 -.-&gt; DN4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;핵심 특성&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;큰 블록 (128 MB 기본)&lt;/strong&gt;: 파일당 블록 수 감소 -&gt; NameNode 부담 감소, sequential I/O 최적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;복제 계수 3&lt;/strong&gt; (기본): 노드/랙/데이터센터 장애에 대비&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write-Once-Read-Many&lt;/strong&gt;: append 만 가능, 임의 수정 불가 (log-structured 사고)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rack awareness&lt;/strong&gt;: 복제본을 다른 랙에 분산 (물리 장애 격리)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;한계&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NameNode 는 단일 지점 병목&lt;/strong&gt; (HA 로 완화)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;작은 파일 다수&lt;/strong&gt; 는 부적합 (파일당 블록 오버헤드)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;저지연 요구&lt;/strong&gt; (&amp;#x3C; 100 ms) 부적합 (배치 지향)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;클라우드 시대에는 [[aws-s3|S3]] 같은 객체 저장소가 사실상 HDFS 를 대체 ([[aws-emr|EMR]] 은 EMRFS 로 S3 를 HDFS 처럼 접근).&lt;/p&gt;
&lt;h3 id=&quot;mapreduce&quot;&gt;MapReduce&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;큰 데이터를 작은 조각으로 나눠 병렬 처리 -&gt; 결과를 합치는&lt;/em&gt; 프로그래밍 모델. Google 이 2004 년에 발표.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Input[(&quot;입력 데이터&amp;#x3C;br/&gt;여러 블록&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Map[&quot;Map 단계 (병렬)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        M1[&quot;Mapper 1&amp;#x3C;br/&gt;(k,v) 방출&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        M2[&quot;Mapper 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        M3[&quot;Mapper N&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Shuffle[&quot;Shuffle 단계&amp;#x3C;br/&gt;(네트워크 재분배)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S[&quot;같은 key 는 같은 reducer 로&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Reduce[&quot;Reduce 단계 (병렬)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        R1[&quot;Reducer 1&amp;#x3C;br/&gt;집계&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        R2[&quot;Reducer 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Output[(&quot;결과&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Input --&gt; M1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Input --&gt; M2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Input --&gt; M3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    M1 --&gt; S&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    M2 --&gt; S&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    M3 --&gt; S&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    S --&gt; R1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    S --&gt; R2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R1 --&gt; Output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R2 --&gt; Output&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;예: WordCount&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Map:    &quot;hello world&quot; → [(&quot;hello&quot;, 1), (&quot;world&quot;, 1)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Shuffle: 같은 word 를 같은 reducer 로 보냄&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Reduce: [(&quot;hello&quot;, 1), (&quot;hello&quot;, 1), ...] → (&quot;hello&quot;, 42)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;MapReduce 의 한계&lt;/strong&gt; (Spark 등장의 이유):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;단계마다 디스크 write&lt;/strong&gt; (Map 결과 -&gt; disk -&gt; Shuffle -&gt; disk -&gt; Reduce)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;반복 알고리즘&lt;/strong&gt; (ML 학습, PageRank) 이 매우 느림 (매 iteration 마다 디스크 왕복)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;표현력 제한&lt;/strong&gt; (map + reduce 로 표현 어려운 알고리즘 다수)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;yarn-yet-another-resource-negotiator&quot;&gt;YARN (Yet Another Resource Negotiator)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;컴퓨트 자원 (CPU, 메모리) 을 여러 애플리케이션에 분배&lt;/em&gt; 하는 스케줄러. Hadoop 2.x 부터 MapReduce 로부터 분리.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;구성&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ResourceManager&lt;/strong&gt; (마스터): 전체 자원 스케줄링&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeManager&lt;/strong&gt; (워커): 각 노드의 컨테이너 관리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ApplicationMaster&lt;/strong&gt; (앱별): 애플리케이션의 태스크 조율&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;YARN 위에서 MapReduce, Spark, Flink, Hive 등이 함께 실행 가능 -&gt; Hadoop 이 &lt;em&gt;단일 처리 엔진이 아닌 플랫폼&lt;/em&gt; 이 됨.&lt;/p&gt;
&lt;h2 id=&quot;spark-의-등장&quot;&gt;Spark 의 등장&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;“디스크 I/O 를 줄이자”&lt;/em&gt; 가 핵심 통찰.&lt;/p&gt;
&lt;h3 id=&quot;rdd-resilient-distributed-dataset&quot;&gt;RDD (Resilient Distributed Dataset)&lt;/h3&gt;
&lt;p&gt;Spark 의 원류 추상. &lt;em&gt;메모리에 분산 저장된 불변 컬렉션&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“Resilient” 의 의미&lt;/strong&gt;: 데이터 자체를 복제해서 저장하지 않고, &lt;em&gt;데이터를 만드는 계보 (lineage)&lt;/em&gt; 만 저장. 노드 장애 시 lineage 를 다시 실행해 복구.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;raw = sc.textFile(&quot;s3://.../logs&quot;)           # RDD 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;words = raw.flatMap(lambda l: l.split())      # RDD 2 (lineage: raw → flatMap)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;counts = words.map(lambda w: (w, 1))          # RDD 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;result = counts.reduceByKey(lambda a, b: a+b) # RDD 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;result.saveAsTextFile(&quot;s3://.../out&quot;)         # Action&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transformation&lt;/strong&gt; (map, filter, join): 지연 실행 (lazy), lineage 만 기록&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action&lt;/strong&gt; (count, collect, save): 실제 실행 트리거&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dag-스케줄러&quot;&gt;DAG 스케줄러&lt;/h3&gt;
&lt;p&gt;Transformation 을 DAG (Directed Acyclic Graph) 로 표현 -&gt; &lt;strong&gt;stage&lt;/strong&gt; (shuffle 경계) 로 나눔 -&gt; &lt;strong&gt;task&lt;/strong&gt; 로 분해 -&gt; executor 에서 병렬 실행.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Stage1[&quot;Stage 1 (narrow deps)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        T1[Read] --&gt; T2[Filter] --&gt; T3[Map]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Boundary[&quot;Shuffle 경계&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S[&quot;ShuffleWrite/Read&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Stage2[&quot;Stage 2 (narrow deps)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        T4[Combine] --&gt; T5[Output]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Stage1 --&gt; S --&gt; Stage2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Narrow dependency&lt;/strong&gt; (map, filter): 파티션 1 → 파티션 1 (shuffle X)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wide dependency&lt;/strong&gt; (groupBy, join): 파티션 다수 → 파티션 재분배 (shuffle O)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Shuffle 이 성능 병목이므로 &lt;em&gt;shuffle 을 최소화&lt;/em&gt; 하는 게 Spark 튜닝의 핵심.&lt;/p&gt;
&lt;h3 id=&quot;dataframe--dataset-2015&quot;&gt;DataFrame / Dataset (2015+)&lt;/h3&gt;
&lt;p&gt;RDD 는 저수준. &lt;em&gt;Catalyst Optimizer&lt;/em&gt; 가 최적화할 수 있도록 &lt;strong&gt;스키마와 SQL 문법&lt;/strong&gt; 을 얹은 것이 DataFrame / Dataset.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# RDD (저수준, 최적화 여지 없음)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;raw.filter(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; r: r[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).map(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; r: (r[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;], r[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# DataFrame (Catalyst 가 파티션 프루닝, 컬럼 프루닝, predicate pushdown 자동)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;df.select(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;amount&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).filter(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;amount &gt; 100&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# SQL (같은 최적화 자동)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;spark.sql(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;SELECT id, amount FROM t WHERE amount &gt; 100&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Catalyst 가 자동으로&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Predicate pushdown ([[apache-parquet|Parquet]] statistics 활용)&lt;/li&gt;
&lt;li&gt;Column pruning&lt;/li&gt;
&lt;li&gt;Constant folding&lt;/li&gt;
&lt;li&gt;Join reordering&lt;/li&gt;
&lt;li&gt;Whole-stage code generation (Java bytecode 생성)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현대에는 &lt;strong&gt;DataFrame API + SQL&lt;/strong&gt; 이 사실상 표준. RDD 는 직접 사용 드묾.&lt;/p&gt;
&lt;h3 id=&quot;아키텍처&quot;&gt;아키텍처&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Driver[&quot;Driver 프로세스&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Main[&quot;사용자 코드 main()&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DAG[&quot;DAG Scheduler&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Task[&quot;Task Scheduler&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph CM[&quot;Cluster Manager&amp;#x3C;br/&gt;(YARN / K8s / Standalone)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        RM[&quot;자원 할당&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Workers[&quot;Executor JVM 들&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E1[&quot;Executor 1&amp;#x3C;br/&gt;(N task slot)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E2[&quot;Executor 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E3[&quot;Executor N&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Main --&gt; DAG&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DAG --&gt; Task&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Task --&gt;|&quot;task 제출&quot;| CM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CM --&gt; E1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CM --&gt; E2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CM --&gt; E3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    E1 -.-&gt;|&quot;결과 반환&quot;| Driver&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Driver&lt;/strong&gt;: 사용자 코드 실행, DAG 생성, 태스크 분배&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Executor&lt;/strong&gt;: 실제 데이터 처리 (여러 task 동시 실행 = slot)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cluster Manager&lt;/strong&gt;: 자원 할당 (YARN / [[aws-emr|EMR]] / K8s / Standalone)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;spark-컴포넌트&quot;&gt;Spark 컴포넌트&lt;/h3&gt;
&lt;p&gt;Spark 는 &lt;em&gt;하나의 엔진&lt;/em&gt; 위에 여러 상위 라이브러리 제공.&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;컴포넌트&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;용도&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Spark Core&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;RDD, DAG, 실행 엔진&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Spark SQL&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DataFrame + SQL 쿼리 (Catalyst 최적화)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Structured Streaming&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DataFrame API 로 스트리밍 (micro-batch or continuous)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MLlib&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;분산 머신러닝 (일부 알고리즘)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;GraphX&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;그래프 분석 (거의 사용 안 됨, GraphFrames 로 대체)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;mapreduce-vs-spark&quot;&gt;MapReduce vs Spark&lt;/h2&gt;























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;MapReduce&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Spark&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단계마다 디스크&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;메모리 우선 (부족 시 디스크 spill)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;모델&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Map + Reduce 2 단계&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;임의 DAG (map, filter, join, groupBy, …)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;속도&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;기준&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10-100 배 (반복 알고리즘)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Java 위주&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Scala, Python, R, SQL, Java&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;상호작용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;배치 only&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;REPL / 노트북 (Zeppelin, Jupyter)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;스트리밍&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;X (Storm 별도)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Structured Streaming&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ML&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Mahout 별도&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MLlib 내장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;표현력&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음 (SQL, DataFrame, MLlib)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;디버깅&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;어려움&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Spark UI&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;결론&lt;/strong&gt;: 새 프로젝트는 사실상 &lt;strong&gt;Spark&lt;/strong&gt;. MapReduce 는 레거시 유지만.&lt;/p&gt;
&lt;h2 id=&quot;관리형-spark--hadoop&quot;&gt;관리형 Spark / Hadoop&lt;/h2&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;서비스&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-emr|Amazon EMR]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Hadoop 생태계 완전 관리형, EC2/Serverless/EKS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-glue|AWS Glue]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버리스 Spark ETL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Databricks&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Spark 창시자들의 상용, Delta Lake&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Google Dataproc&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GCP 관리형&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Azure HDInsight / Synapse&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Azure&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;자체 호스팅&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cloudera, Hortonworks (인수 통합)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;언제-spark-를-쓰나&quot;&gt;언제 Spark 를 쓰나&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;적합&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;수 GB ~ PB 규모 배치 처리&lt;/li&gt;
&lt;li&gt;ETL 파이프라인 (raw -&gt; 정제)&lt;/li&gt;
&lt;li&gt;ML 특징 엔지니어링 + 학습&lt;/li&gt;
&lt;li&gt;대규모 join / aggregation&lt;/li&gt;
&lt;li&gt;반복 알고리즘 (K-means, GraphX, PageRank)&lt;/li&gt;
&lt;li&gt;로그/이벤트 스트림 분석 (Structured Streaming)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;부적합 (더 나은 대안)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;초저지연 (&amp;#x3C; 100 ms) 처리 -&gt; [[aws-kinesis-data-analytics|Flink]] / Kafka Streams&lt;/li&gt;
&lt;li&gt;트랜잭션 처리 -&gt; [[postgresql|Postgres]] / OLTP DB&lt;/li&gt;
&lt;li&gt;작은 데이터 (&amp;#x3C; 10 GB) -&gt; pandas / DuckDB / Polars&lt;/li&gt;
&lt;li&gt;단순 SQL 애드혹 -&gt; [[aws-athena|Athena]] / [[aws-redshift|Redshift]]&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;spark-성능-튜닝의-큰-축&quot;&gt;Spark 성능 튜닝의 큰 축&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;파일 포맷&lt;/strong&gt;: [[apache-parquet|Parquet]] + ZSTD (CSV/JSON 대비 10-100 배)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파티셔닝&lt;/strong&gt;: partition 컬럼으로 프루닝&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shuffle 최소화&lt;/strong&gt;: &lt;code&gt;repartition&lt;/code&gt; 남용 X, broadcast join 활용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Broadcast join&lt;/strong&gt;: 작은 테이블 (~ 100 MB) 을 executor 에 복제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AQE (Adaptive Query Execution)&lt;/strong&gt;: 런타임 통계로 자동 최적화 (Spark 3.x 기본 on)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Executor 크기&lt;/strong&gt;: 너무 크면 GC 문제, 너무 작으면 오버헤드 (경험적 4-8 core, 16-32 GB)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache / Persist&lt;/strong&gt;: 반복 참조 데이터만&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skew 처리&lt;/strong&gt;: Salting, AQE skew join&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;&lt;code&gt;collect()&lt;/code&gt; 를 큰 데이터에&lt;/strong&gt; = Driver OOM. Driver 는 단일 JVM. 큰 결과는 &lt;code&gt;write&lt;/code&gt; / &lt;code&gt;foreachPartition&lt;/code&gt; 로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Shuffle 남용&lt;/strong&gt;. &lt;code&gt;groupBy&lt;/code&gt;, &lt;code&gt;join&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;repartition&lt;/code&gt; 는 shuffle. Wide dependency 를 반복하면 성능 급락.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;작은 파일 (Small files) 수천 개&lt;/strong&gt; = task 수 폭증 + 스케줄링 오버헤드. Compaction 후 read.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;UDF 는 Catalyst 최적화 우회&lt;/strong&gt;. 가능하면 built-in 함수 사용. Python UDF 는 특히 느림 (직렬화 오버헤드).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Skewed key&lt;/strong&gt; = 특정 task 만 오래 걸림 (전체가 그 task 에 blocked). AQE skew join 또는 salting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;HDFS 는 클라우드에서 임시&lt;/strong&gt;. [[aws-emr|EMR]] 등에서 클러스터 종료 시 데이터 손실. 결과는 [[aws-s3|S3]] 에.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;RDD 직접 사용 지양&lt;/strong&gt;. DataFrame / SQL 이 Catalyst 최적화 받아 훨씬 빠름. 특수한 경우만 RDD.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[mpp|MPP (대량 병렬 처리)]] - 다른 계보의 분산 처리&lt;/li&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - Spark 의 소비 대상&lt;/li&gt;
&lt;li&gt;[[data-lake|Data Lake]] - Spark 의 저장소&lt;/li&gt;
&lt;li&gt;[[apache-parquet|Apache Parquet]] - Spark 의 표준 포맷&lt;/li&gt;
&lt;li&gt;[[etl|ETL / ELT]] - Spark 의 대표 워크로드&lt;/li&gt;
&lt;li&gt;[[aws-emr|Amazon EMR]] - AWS 관리형 Hadoop/Spark&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - 서버리스 Spark ETL&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - Trino 기반 SQL 대안&lt;/li&gt;
&lt;li&gt;[[aws-s3|AWS S3]] - HDFS 대체 저장소&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>hadoop</category><category>spark</category><category>big-data</category><category>distributed</category><author>koa (김신건)</author></item><item><title>MPP (대량 병렬 처리)</title><link>https://shinkeonkim.com/wiki/data-engineering/mpp/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/mpp/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;MPP&lt;/strong&gt; (Massively Parallel Processing, 대량 병렬 처리) 는 &lt;em&gt;하나의 대규모 쿼리를 수십 - 수백 노드에 나눠 동시에 실행하는 아키텍처&lt;/em&gt;. 각 노드가 &lt;strong&gt;자기 데이터 조각만&lt;/strong&gt; 처리한 뒤 결과를 통합. [[data-warehouse|데이터 웨어하우스]] 의 표준 아키텍처.&lt;/p&gt;
&lt;p&gt;대표 시스템: [[aws-redshift|Amazon Redshift]], Snowflake, Google BigQuery, Teradata, Greenplum, Vertica, IBM Netezza, ClickHouse.&lt;/p&gt;
&lt;h2 id=&quot;왜-mpp-인가&quot;&gt;왜 MPP 인가&lt;/h2&gt;
&lt;p&gt;단일 서버 DB ([[postgresql|Postgres]], MySQL) 는 CPU / 메모리 / 디스크 자원이 한계. 100 억 행 aggregation 은 시간 단위로 느려짐.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MPP 의 답&lt;/strong&gt;: &lt;em&gt;데이터를 여러 노드에 나눠 저장하고, 쿼리를 각 노드에서 병렬 실행&lt;/em&gt;. 노드 100 개면 이론상 100 배 빠름 (실제로는 shuffle 오버헤드 등으로 낮음).&lt;/p&gt;
&lt;h2 id=&quot;세-가지-분산-아키텍처&quot;&gt;세 가지 분산 아키텍처&lt;/h2&gt;
&lt;p&gt;MPP 를 이해하려면 &lt;em&gt;분산 시스템의 세 축&lt;/em&gt; 을 알아야 함.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph SM[&quot;Shared-Memory&amp;#x3C;br/&gt;(단일 서버)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        CPU1[CPU] --&gt; Mem[공유 메모리]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        CPU2[CPU] --&gt; Mem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Mem --&gt; Disk[디스크]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph SD[&quot;Shared-Disk&amp;#x3C;br/&gt;(Oracle RAC)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        N1[Node 1] --&gt; SDisk[공유 스토리지]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        N2[Node 2] --&gt; SDisk&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        N3[Node 3] --&gt; SDisk&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph SN[&quot;Shared-Nothing&amp;#x3C;br/&gt;(MPP)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        NN1[Node 1] --&gt; D1[로컬 디스크 1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        NN2[Node 2] --&gt; D2[로컬 디스크 2]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        NN3[Node 3] --&gt; D3[로컬 디스크 3]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        NN1 &amp;#x3C;-.-&gt;|&quot;네트워크&quot;| NN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        NN2 &amp;#x3C;-.-&gt;|&quot;네트워크&quot;| NN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Shared-Memory&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Shared-Disk&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Shared-Nothing (MPP)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;자원&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CPU/메모리 공유&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;디스크 공유&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;각자 소유&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;확장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Scale-up (단일 서버 강화)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Scale-out (제한적)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Scale-out (선형 확장)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;동시성&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;락 경합&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;락 경합 (분산 락)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음 (독립)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;장애 격리&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버 전체 다운&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;디스크 SPOF&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;노드 하나만&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;네트워크 부담&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큼 (shuffle)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;대표&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단일 [[postgresql|Postgres]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Oracle RAC&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Redshift, Snowflake&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;MPP 는 shared-nothing&lt;/strong&gt; = &lt;em&gt;각 노드가 자기 자원을 완전 소유&lt;/em&gt;. 네트워크로만 통신. 노드 수를 늘리면 (거의) 선형으로 성능 증가.&lt;/p&gt;
&lt;h2 id=&quot;mpp-클러스터-구조&quot;&gt;MPP 클러스터 구조&lt;/h2&gt;
&lt;p&gt;전형적인 MPP 는 &lt;strong&gt;leader + compute&lt;/strong&gt; 로 구성.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Client[&quot;BI / JDBC / ODBC 클라이언트&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Client --&gt; Leader&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Cluster[&quot;MPP 클러스터&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Leader[&quot;Leader Node&amp;#x3C;br/&gt;(쿼리 파싱/최적화/조율)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph Compute[&quot;Compute Nodes (실제 데이터 처리)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            CN1[&quot;Compute 1&amp;#x3C;br/&gt;slice 1, slice 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            CN2[&quot;Compute 2&amp;#x3C;br/&gt;slice 3, slice 4&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            CN3[&quot;Compute N&amp;#x3C;br/&gt;slice N-1, slice N&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Leader --&gt;|&quot;실행 계획 배포&quot;| CN1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Leader --&gt;|&quot;실행 계획 배포&quot;| CN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Leader --&gt;|&quot;실행 계획 배포&quot;| CN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        CN1 &amp;#x3C;-.-&gt;|&quot;redistribution&quot;| CN2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        CN2 &amp;#x3C;-.-&gt;|&quot;redistribution&quot;| CN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        CN1 &amp;#x3C;-.-&gt; CN3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;leader-node&quot;&gt;Leader Node&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트 연결 종단&lt;/li&gt;
&lt;li&gt;SQL 파싱, 검증&lt;/li&gt;
&lt;li&gt;쿼리 최적화 (통계 기반)&lt;/li&gt;
&lt;li&gt;실행 계획을 compute node 에 배포&lt;/li&gt;
&lt;li&gt;각 compute 의 부분 결과를 통합해 클라이언트에 반환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터를 직접 처리하지 않음&lt;/strong&gt; (조율만)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;compute-node&quot;&gt;Compute Node&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실제 데이터 저장 + 처리&lt;/li&gt;
&lt;li&gt;여러 &lt;strong&gt;slice&lt;/strong&gt; (병렬 실행 단위) 로 분할 (노드당 코어 수 만큼)&lt;/li&gt;
&lt;li&gt;Leader 로부터 받은 실행 계획을 자기 slice 에서 실행&lt;/li&gt;
&lt;li&gt;필요 시 다른 노드로 데이터 재분배 (&lt;strong&gt;shuffle / redistribution&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;데이터-분산-전략-distribution&quot;&gt;데이터 분산 전략 (Distribution)&lt;/h2&gt;
&lt;p&gt;MPP 의 성능은 &lt;em&gt;데이터를 어떻게 노드에 나눠놓았는가&lt;/em&gt; 에 좌우.&lt;/p&gt;
&lt;h3 id=&quot;1-hash-distribution-key&quot;&gt;1. Hash Distribution (Key)&lt;/h3&gt;
&lt;p&gt;특정 컬럼 값을 hash 해서 slice 결정.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;customer_id 1  → hash → slice 3 (Node 2)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;customer_id 42 → hash → slice 7 (Node 4)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 같은 key 를 조인 시 &lt;strong&gt;co-located join&lt;/strong&gt; (네트워크 이동 없음).&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- customers.customer_id 로 hash 분산&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- orders.customer_id 로 hash 분산&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 같은 key -&gt; 같은 slice -&gt; 로컬 join&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;SELECT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ... &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; customers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;JOIN&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; orders &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ON&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; customers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_id&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; orders&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;customer_id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;: &lt;strong&gt;skew&lt;/strong&gt; (특정 key 에 몰림) 시 그 slice 만 과부하.&lt;/p&gt;
&lt;h3 id=&quot;2-round-robin--even&quot;&gt;2. Round-Robin / EVEN&lt;/h3&gt;
&lt;p&gt;행을 순서대로 다음 slice 에 배정. 균등 분산.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: skew 없음, 완전 균등.
&lt;strong&gt;단점&lt;/strong&gt;: 조인 시 항상 redistribute 필요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;적합&lt;/strong&gt;: 조인 안 하는 fact table, 로그.&lt;/p&gt;
&lt;h3 id=&quot;3-replicated--all&quot;&gt;3. Replicated / ALL&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;모든 노드에 같은 복사본&lt;/em&gt;. 작은 dimension table 에.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 어떤 fact table 과도 조인 시 redistribute 불필요.
&lt;strong&gt;단점&lt;/strong&gt;: 저장 공간 N 배 (N = 노드 수).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;적합&lt;/strong&gt;: 수백만 행 이하 dimension (date_dim, product_dim).&lt;/p&gt;
&lt;h3 id=&quot;4-automatic&quot;&gt;4. Automatic&lt;/h3&gt;
&lt;p&gt;시스템이 데이터 크기 / 접근 패턴 기반으로 자동 선택. Redshift AUTO, Snowflake 자동 등.&lt;/p&gt;
&lt;h2 id=&quot;쿼리-실행-흐름&quot;&gt;쿼리 실행 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant C as Client&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant L as Leader&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant N1 as Compute 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant N2 as Compute 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant N3 as Compute 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    C-&gt;&gt;L: SQL 쿼리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L-&gt;&gt;L: 파싱, 최적화, 계획 수립&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    par 각 노드에서 병렬 스캔&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        L-&gt;&gt;N1: 스캔 + 필터 (자기 slice 데이터만)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        L-&gt;&gt;N2: 스캔 + 필터&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        L-&gt;&gt;N3: 스캔 + 필터&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N1--&gt;&gt;N1: 부분 aggregate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N2--&gt;&gt;N2: 부분 aggregate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N3--&gt;&gt;N3: 부분 aggregate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over N1,N3: 필요 시 redistribution&amp;#x3C;br/&gt;(GROUP BY 등)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N1--&gt;&gt;L: 부분 결과&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N2--&gt;&gt;L: 부분 결과&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    N3--&gt;&gt;L: 부분 결과&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L-&gt;&gt;L: 최종 통합&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L--&gt;&gt;C: 결과&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;핵심 통찰&lt;/strong&gt;: &lt;em&gt;가능한 한 각 노드에서 부분 aggregate 를 먼저&lt;/em&gt; 하고 (예: 각 노드에서 COUNT), 마지막에 leader 가 합침 (SUM of COUNTs). 이걸 못하면 모든 원본 데이터를 leader 로 모아야 함.&lt;/p&gt;
&lt;h2 id=&quot;redistribution-shuffle&quot;&gt;Redistribution (Shuffle)&lt;/h2&gt;
&lt;p&gt;같은 join key 가 다른 노드에 있으면, 조인 전에 &lt;strong&gt;네트워크로 재분배&lt;/strong&gt; 필요.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Case 1: co-located join (좋음)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  customer.customer_id = order.customer_id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  둘 다 customer_id 로 hash 분산 -&gt; 같은 slice -&gt; 로컬 join&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Case 2: redistribute (나쁨)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  customer.customer_id = order.city&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  order 를 customer_id 로 redistribute -&gt; 네트워크 이동 -&gt; 느림&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Case 3: broadcast (dimension 작을 때)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  small dim × huge fact&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  small dim 을 모든 노드에 복사 -&gt; 각 노드에서 로컬 join&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Redistribution 이 성능 병목&lt;/strong&gt;. 실행 계획 (&lt;code&gt;EXPLAIN&lt;/code&gt;) 에서 &lt;code&gt;DS_DIST_INNER&lt;/code&gt;, &lt;code&gt;DS_BCAST_INNER&lt;/code&gt; 등을 확인.&lt;/p&gt;
&lt;h2 id=&quot;mpp-의-강점&quot;&gt;MPP 의 강점&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;선형 확장성&lt;/strong&gt;: 노드 2 배 -&gt; 처리량 (거의) 2 배&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컬럼형 저장 최적&lt;/strong&gt;: 컬럼 단위로 압축 + 필요 컬럼만 스캔&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;대규모 aggregation&lt;/strong&gt;: SUM, COUNT, GROUP BY 가 병렬로 나뉨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분석 쿼리 특화&lt;/strong&gt;: OLAP 워크로드에 이상적&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;mpp-의-한계&quot;&gt;MPP 의 한계&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;작은 트랜잭션 부적합&lt;/strong&gt;: INSERT 한 행씩은 매우 느림 (bulk COPY 필요)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JOIN 이 잘못 설계되면&lt;/strong&gt; 성능 급락 (redistribution 폭탄)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 skew&lt;/strong&gt; 에 취약 (한 slice 만 과부하)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동시 사용자 한계&lt;/strong&gt; (leader 병목)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비싼 노드&lt;/strong&gt;: 스토리지 + 컴퓨트가 결합 -&gt; 확장 유연성 낮음&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;현대-mpp-compute-storage-분리&quot;&gt;현대 MPP: Compute-Storage 분리&lt;/h2&gt;
&lt;p&gt;전통 MPP (Netezza, Teradata) 는 노드 안에 로컬 SSD/HDD 저장. Compute 를 늘리려면 스토리지도 함께.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;현대&lt;/strong&gt; (Snowflake 2015+, Redshift RA3, BigQuery) 는 &lt;strong&gt;compute 와 storage 를 분리&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Old[&quot;전통 MPP (~2010)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        N1[Node = compute + storage] --&gt; D1[로컬 SSD]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        N2[Node = compute + storage] --&gt; D2[로컬 SSD]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph New[&quot;현대 MPP (Snowflake, Redshift RA3)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph CT[&quot;Compute 티어&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            C1[Compute]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            C2[Compute]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        subgraph ST[&quot;Storage 티어&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            S3[&quot;공유 스토리지&amp;#x3C;br/&gt;(S3 / 자체)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        C1 &amp;#x3C;--&gt; S3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        C2 &amp;#x3C;--&gt; S3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;이점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compute 만 늘리기 / 줄이기 가능 (탄력적)&lt;/li&gt;
&lt;li&gt;여러 워크로드가 같은 데이터 공유 (data sharing)&lt;/li&gt;
&lt;li&gt;스토리지는 사실상 무한 (S3)&lt;/li&gt;
&lt;li&gt;유휴 시 compute 만 종료 (비용 절감)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;대표 사례&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[aws-redshift-serverless|Redshift Serverless]]: compute 완전 자동 스케일&lt;/li&gt;
&lt;li&gt;Snowflake: multi-cluster virtual warehouse&lt;/li&gt;
&lt;li&gt;BigQuery: 서버리스, slot 예약&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;mpp-vs-spark-분산-처리의-두-계보&quot;&gt;MPP vs Spark (분산 처리의 두 계보)&lt;/h2&gt;
&lt;p&gt;같은 “분산 대규모 처리” 지만 철학이 다름.&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;MPP&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;[[hadoop-spark|Spark]]&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;주 목적&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;분석 SQL 쿼리&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;임의 데이터 처리 (ETL, ML, 스트리밍)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자체 (컬럼형, 최적화)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;외부 ([[aws-s3|S3]], HDFS)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;인터페이스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SQL 중심&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DataFrame, RDD, SQL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;자원 모델&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;클러스터 고정 or 자동&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Executor 온디맨드&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;실행 모델&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Push-based (leader → compute)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DAG based, lazy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;최적화&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cost-based optimizer (통계)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Catalyst (스키마 기반)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;적합&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BI, 대시보드, 반복 SQL&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ETL, ML, 임시 대량 처리&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;대표&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Redshift, Snowflake&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Databricks, [[aws-emr|EMR]], [[aws-glue|Glue]]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;현대는 융합&lt;/strong&gt;: [[aws-redshift-spectrum|Redshift Spectrum]] 은 S3 (data lake) 쿼리, Databricks 는 Delta Lake + Photon (MPP 스타일 벡터화) -&gt; &lt;strong&gt;Lakehouse&lt;/strong&gt; 방향.&lt;/p&gt;
&lt;h2 id=&quot;대표-mpp-시스템&quot;&gt;대표 MPP 시스템&lt;/h2&gt;

















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;시스템&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-redshift|Amazon Redshift]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;PostgreSQL 기반 MPP, RA3 (compute-storage 분리), Serverless&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Multi-cloud, virtual warehouse, 데이터 공유 우수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Google BigQuery&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버리스, Dremel 기반, slot 모델&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Databricks SQL&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Delta Lake + Photon (벡터화 엔진)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Teradata&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원조 MPP (1979-), 온프렘 대세&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Greenplum&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스 (PostgreSQL 기반, VMware Tanzu)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Vertica&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컬럼형 MPP, 광고/통신 산업&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ClickHouse&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스, 실시간 분석 특화, 매우 빠름&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;IBM Netezza&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;하드웨어 어플라이언스 원조&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Firebolt&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;신생, 성능 강조&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;행 단위 INSERT/UPDATE&lt;/strong&gt; = MPP 의 최악의 워크로드. bulk load (COPY, [[apache-parquet|Parquet]] batch) 만.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;분산 키 설계 실수&lt;/strong&gt; = redistribution 폭탄. 자주 조인하는 컬럼을 distribution key 로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;데이터 skew&lt;/strong&gt; (특정 key 에 몰림) = 한 slice 만 과부하, 전체 쿼리가 그 slice 에 blocked. Cardinality 확인.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;작은 dimension 을 hash 분산&lt;/strong&gt; 하면 조인마다 redistribute. ALL / replicated 로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;&lt;code&gt;SELECT *&lt;/code&gt;&lt;/strong&gt; = 컬럼형의 이점 상실. 필요 컬럼만.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;동시 사용자 많음&lt;/strong&gt; = leader node 병목. Concurrency scaling / Serverless 로 완화.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;MPP 는 OLTP 대체 X&lt;/strong&gt;. 트랜잭션 워크로드는 [[postgresql|Postgres]] 같은 OLTP DB. MPP 는 OLAP 전용.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - MPP 의 주 응용&lt;/li&gt;
&lt;li&gt;[[hadoop-spark|Hadoop / Spark]] - 다른 분산 처리 계보&lt;/li&gt;
&lt;li&gt;[[aws-redshift|Amazon Redshift]] - AWS MPP DW&lt;/li&gt;
&lt;li&gt;[[aws-redshift-serverless|Redshift Serverless]] - MPP 서버리스&lt;/li&gt;
&lt;li&gt;[[apache-parquet|Apache Parquet]] - 컬럼형 저장 포맷&lt;/li&gt;
&lt;li&gt;[[sharding-vs-partitioning|샤딩 vs 파티셔닝]] - 분산 저장 원리&lt;/li&gt;
&lt;li&gt;[[postgresql|PostgreSQL]] - Shared-memory 대비&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - Trino 기반 서버리스 대안&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>mpp</category><category>distributed</category><category>database</category><category>olap</category><category>architecture</category><author>koa (김신건)</author></item><item><title>데이터 레이크</title><link>https://shinkeonkim.com/wiki/data-engineering/data-lake/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/data-lake/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;데이터 레이크&lt;/strong&gt; (Data Lake) 는 &lt;em&gt;구조 여부와 무관하게 모든 종류의 데이터를 원본 형식 그대로 저장하는 중앙 저장소&lt;/em&gt;. 스키마를 미리 강제하지 않고 (&lt;em&gt;schema-on-read&lt;/em&gt;), 필요할 때 쿼리 엔진 / 프레임워크가 스키마를 해석. [[aws-s3|S3]] / GCS / Azure Data Lake Storage 가 사실상 표준 백엔드.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;핵심 대비&lt;/strong&gt;: [[data-warehouse|데이터 웨어하우스]] 는 &lt;em&gt;schema-on-write&lt;/em&gt; (미리 정제된 데이터), 데이터 레이크는 &lt;em&gt;schema-on-read&lt;/em&gt; (원본 저장 후 해석).&lt;/p&gt;
&lt;h2 id=&quot;왜-데이터-레이크인가&quot;&gt;왜 데이터 레이크인가&lt;/h2&gt;
&lt;p&gt;전통 [[data-warehouse|DW]] 만으로는 부족한 이유:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;비정형 / 반정형&lt;/strong&gt; 데이터 (로그, JSON, 이미지, 오디오, 비디오) 를 DW 에 넣기 어려움&lt;/li&gt;
&lt;li&gt;DW 저장은 비쌈, 원본 raw 를 모두 DW 에 두면 비용 폭발&lt;/li&gt;
&lt;li&gt;ML 학습은 종종 &lt;em&gt;원본 그대로&lt;/em&gt; 가 필요 (변환된 것이 아닌)&lt;/li&gt;
&lt;li&gt;데이터 소스가 폭증 -&gt; 스키마 강제가 병목&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;데이터 레이크의 답&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[aws-s3|S3]] 같은 저비용 객체 스토리지에 원본 그대로 저장&lt;/li&gt;
&lt;li&gt;소비 시점에 필요한 엔진이 스키마 해석 ([[aws-athena|Athena]] SQL, [[aws-emr|EMR]] Spark, ML 학습)&lt;/li&gt;
&lt;li&gt;여러 워크로드가 &lt;em&gt;같은 데이터 한 벌&lt;/em&gt; 을 공유&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;데이터-레이크-vs-데이터-웨어하우스&quot;&gt;데이터 레이크 vs 데이터 웨어하우스&lt;/h2&gt;

































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Data Lake&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;[[data-warehouse|Data Warehouse]]&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;주 저장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원본 파일 ([[apache-parquet|Parquet]], JSON, CSV, 이미지, …)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정제된 컬럼형 테이블&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;스키마&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Schema-on-read&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Schema-on-write&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;엔진&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다양 ([[aws-athena|Athena]], [[aws-emr|EMR]], Spark, Presto)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자체 SQL ([[aws-redshift|Redshift]], BigQuery)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;데이터 종류&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;구조 + 반구조 + 비구조 (전부)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;구조 (테이블)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장 비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 저렴 ([[aws-s3|S3]] $0.023/GB)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;비쌈 (Redshift RMS 등)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;컴퓨트 비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;쿼리별 과금 (스캔량)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;클러스터 시간&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;워크로드&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ML, batch, 로그, 애드혹&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BI, 대시보드, SQL 분석&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;트랜잭션&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음 (원시), Iceberg/Delta 로 가능&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;거버넌스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;어려움 ([[aws-lake-formation|Lake Formation]])&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;성숙&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;거버넌스 안 잡히면&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;em&gt;data swamp&lt;/em&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사일로&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;대표 스택&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-s3|S3]] + [[aws-glue|Glue]] + [[aws-athena|Athena]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-redshift|Redshift]] / Snowflake / BigQuery&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;현대적 결론&lt;/strong&gt;: &lt;em&gt;둘 중 하나&lt;/em&gt; 가 아님. &lt;strong&gt;Lakehouse&lt;/strong&gt; 로 통합하는 방향 (아래).&lt;/p&gt;
&lt;h2 id=&quot;데이터-레이크-vs-데이터-웨어하우스-vs-레이크하우스&quot;&gt;데이터 레이크 vs 데이터 웨어하우스 vs 레이크하우스&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph DW[&quot;Data Warehouse (전통)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DW_S[&quot;정제된 컬럼형 저장&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DW_E[&quot;자체 SQL 엔진&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DW_A[&quot;ACID 트랜잭션&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph DL[&quot;Data Lake (2010s)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DL_S[&quot;원본 파일 저장&amp;#x3C;br/&gt;Parquet/JSON/Image&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DL_E[&quot;여러 엔진 (Athena, Spark, ...)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DL_N[&quot;트랜잭션 없음&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph LH[&quot;Data Lakehouse (현재)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        LH_S[&quot;원본 파일 저장 + 트랜잭션 메타&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        LH_F[&quot;Iceberg / Delta / Hudi&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        LH_A[&quot;ACID + Time travel + Schema evolution&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DW -.-&gt; LH&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DL -.-&gt; LH&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Lakehouse&lt;/strong&gt; = 데이터 레이크의 유연성 + DW 의 트랜잭션/거버넌스. Apache &lt;strong&gt;Iceberg&lt;/strong&gt;, &lt;strong&gt;Delta Lake&lt;/strong&gt;, &lt;strong&gt;Apache Hudi&lt;/strong&gt; 같은 오픈 테이블 포맷이 핵심.&lt;/p&gt;
&lt;h2 id=&quot;데이터-조직화-계층-zones&quot;&gt;데이터 조직화: 계층 (Zones)&lt;/h2&gt;
&lt;p&gt;원본 그대로 다 섞이면 &lt;em&gt;data swamp&lt;/em&gt; 가 됨. 계층을 나누는 것이 표준.&lt;/p&gt;
&lt;h3 id=&quot;medallion-databricks-대중화&quot;&gt;Medallion (Databricks 대중화)&lt;/h3&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;계층&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;별칭&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;내용&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Bronze&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Raw&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소스에서 온 그대로. 재처리 가능하도록 immutable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Silver&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cleaned&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;타입 정리, dedup, join 가능한 상태&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Gold&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Curated&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;비즈니스 도메인별 aggregate. BI 소비&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;kimball-스타일-전통-dw-관용&quot;&gt;Kimball 스타일 (전통 DW 관용)&lt;/h3&gt;





















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;계층&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;내용&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Landing / Staging&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원본 착륙&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Core / Integrated&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정규화된 통합 저장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Marts&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;비즈니스별 fact/dim&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;둘은 사실상 같은 개념&lt;/strong&gt;. 이름과 표기가 다를 뿐.&lt;/p&gt;
&lt;h2 id=&quot;표준-아키텍처-aws-위&quot;&gt;표준 아키텍처 (AWS 위)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Sources&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        DB[(&quot;RDS/Aurora&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Kafka[Kinesis/MSK]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Logs[Application Logs]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SaaS[&quot;SaaS API&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Files[&quot;파일 업로드&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sources --&gt;|&quot;Extract&quot;| Bronze[&quot;S3 Bronze/&amp;#x3C;br/&gt;(raw)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Bronze --&gt;|&quot;Glue Spark&quot;| Silver[&quot;S3 Silver/&amp;#x3C;br/&gt;(Parquet, cleaned)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Silver --&gt;|&quot;CTAS / Spark&quot;| Gold[&quot;S3 Gold/&amp;#x3C;br/&gt;(aggregates)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Catalog[(&quot;Glue Data Catalog&quot;)] -.-&gt;|&quot;schema&quot;| Bronze&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Catalog -.-&gt; Silver&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Catalog -.-&gt; Gold&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Gold --&gt; Athena[&quot;Athena SQL&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Gold --&gt; Spectrum[&quot;Redshift Spectrum&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Gold --&gt; EMR[&quot;EMR Spark&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Gold --&gt; SM[&quot;SageMaker ML&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Athena --&gt; BI[QuickSight]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LF[&quot;Lake Formation&amp;#x3C;br/&gt;(권한/거버넌스)&quot;] -.-&gt; Catalog&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;[[aws-s3|S3]]&lt;/strong&gt;: 저장의 뿌리 (모든 계층)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[[aws-glue|Glue]]&lt;/strong&gt;: 카탈로그 + Spark 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[[aws-lake-formation|Lake Formation]]&lt;/strong&gt;: 세분화된 접근 제어&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[[aws-athena|Athena]] / [[aws-redshift-spectrum|Spectrum]] / [[aws-emr|EMR]]&lt;/strong&gt;: 소비 엔진&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일 포맷&lt;/strong&gt;: [[apache-parquet|Parquet]] + ZSTD 압축이 사실상 표준&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;오픈-테이블-포맷-lakehouse-의-핵심&quot;&gt;오픈 테이블 포맷 (Lakehouse 의 핵심)&lt;/h2&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;지원 엔진&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Apache Iceberg&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AWS/Netflix 표준화, hidden partitioning, schema evolution, snapshot&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-athena|Athena]], [[aws-emr|EMR]], Spark, Trino, Flink&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Delta Lake&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Databricks 원류, transaction log, time travel&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Spark, EMR, Databricks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Apache Hudi&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Uber 원류, upsert 최적화, streaming ingest&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Spark, Flink, [[aws-emr|EMR]]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;공통 기능&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ACID 트랜잭션&lt;/strong&gt; (concurrent read/write)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time travel&lt;/strong&gt; (스냅샷 이력)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schema evolution&lt;/strong&gt; (컬럼 추가/제거)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hidden partitioning&lt;/strong&gt; (사용자가 파티션 계산 안 해도 됨)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compaction / vacuum&lt;/strong&gt; (small files 자동 관리)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2024 이후 방향&lt;/strong&gt;: [[aws-s3|S3]] Tables (관리형 Iceberg), Snowflake Iceberg 지원, Redshift + Iceberg, Databricks + UniForm.&lt;/p&gt;
&lt;h2 id=&quot;s3-데이터-레이크-파일-구조-관용&quot;&gt;S3 데이터 레이크 파일 구조 관용&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;s3://company-data-lake/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── bronze/                              # raw&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── source=rds_orders/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   └── year=2026/month=07/day=30/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │       └── part-00000.parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── source=kinesis_events/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   └── year=2026/month=07/day=30/hour=15/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── silver/                              # cleaned&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── db=analytics/table=orders/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   └── year=2026/month=07/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │       └── part-00000.parquet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── gold/                                # marts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── db=marts/table=daily_sales/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── _catalog/                            # Iceberg/Delta metadata&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── _archive/                            # 오래된 raw (Glacier lifecycle)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── _tmp/                                # 임시 (life 3d)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;파티션 관용&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;시계열&lt;/strong&gt;: &lt;code&gt;year=YYYY/month=MM/day=DD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;다중 소스&lt;/strong&gt;: &lt;code&gt;source=xxx/year=.../...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;테이블 단위&lt;/strong&gt;: &lt;code&gt;db=xxx/table=yyy/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;데이터-레이크-성숙도-단계&quot;&gt;데이터 레이크 성숙도 단계&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Raw dump&lt;/strong&gt;: 소스에서 그대로. 카탈로그 없음. -&gt; &lt;strong&gt;data swamp&lt;/strong&gt; 위험.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cataloged&lt;/strong&gt;: [[aws-glue|Glue Catalog]] 로 스키마 등록. [[aws-athena|Athena]] 로 쿼리 가능.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zoned&lt;/strong&gt;: Bronze/Silver/Gold 계층. 정제/승격 프로세스.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Governed&lt;/strong&gt;: [[aws-lake-formation|Lake Formation]] 로 세분화 권한, PII 관리, lineage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lakehouse&lt;/strong&gt;: Iceberg/Delta 로 트랜잭션, time travel, BI/ML 통합.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;흔한-실패-패턴-data-swamp&quot;&gt;흔한 실패 패턴: Data Swamp&lt;/h2&gt;
&lt;p&gt;정제/카탈로그/권한 없이 데이터만 쌓임 -&gt; 아무도 못 씀.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;증상&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;팀마다 다른 파일을 “orders” 로 부름&lt;/li&gt;
&lt;li&gt;파일이 수백만 개 (small files)&lt;/li&gt;
&lt;li&gt;CSV 파일이 컬럼 순서/개수 다름&lt;/li&gt;
&lt;li&gt;PII 가 사방에 흩어짐&lt;/li&gt;
&lt;li&gt;누가 언제 만든 파일인지 모름&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;예방&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 계약&lt;/strong&gt; (contract): 소스와 파이프라인 간 스키마/의미 합의&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[[aws-glue|Glue Catalog]] 등록&lt;/strong&gt; 필수&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compaction job&lt;/strong&gt;: 작은 파일 -&gt; 256 MB+&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifecycle 정책&lt;/strong&gt;: 오래된 raw 는 [[aws-s3-glacier|Glacier]] 로&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PII 스캔&lt;/strong&gt;: Macie 등으로 자동 탐지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;소유자 (owner) 태그&lt;/strong&gt;: 모든 폴더/테이블에&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;파일-포맷-선택&quot;&gt;파일 포맷 선택&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;데이터 종류&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;이유&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;이벤트 스트림 원본&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JSON / [[apache-parquet|Parquet]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JSON = 유연, Parquet = 쿼리 빠름&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;분석용 정제 데이터&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[apache-parquet|Parquet]] + ZSTD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;압축 + 컬럼 프루닝&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;트랜잭션 필요&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Iceberg / Delta (Parquet 위)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID + time travel&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;임시 / debug&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CSV / JSON&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사람이 읽기 편함&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;이미지 / 오디오&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원본 (binary)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;압축 이미 되어 있음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ML 학습 tensor&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Parquet / TFRecord / WebDataset&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;병렬 read&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;성능--비용의-3-축&quot;&gt;성능 &amp;#x26; 비용의 3 축&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;파일 포맷&lt;/strong&gt; - Parquet vs CSV 는 [[aws-athena|Athena]] 스캔비에서 10-100배 차이&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파티션 프루닝&lt;/strong&gt; - 시계열 파티션으로 스캔 대상 축소&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일 크기&lt;/strong&gt; - 256 MB - 1 GB 범위 (small files 회피)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;자세히: [[apache-parquet|Apache Parquet]], [[aws-athena|Athena]] 함정 섹션.&lt;/p&gt;
&lt;h2 id=&quot;스토리지-계층화-lifecycle&quot;&gt;스토리지 계층화 (Lifecycle)&lt;/h2&gt;
&lt;p&gt;Raw 를 영구 보관하되 비용을 줄이는 관용:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Bronze/ (30일)&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;S3 Standard&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Bronze/ (90일)&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;S3 Standard-IA&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Bronze/ (1년+)&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;S3 Glacier Flexible Retrieval&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Bronze/ (7년+)&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;S3 Glacier Deep Archive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Silver/&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Standard (자주 read)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Gold/&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;              : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Standard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세히: [[aws-s3-glacier|S3 Glacier]], [[aws-s3|S3]] Lifecycle.&lt;/p&gt;
&lt;h2 id=&quot;데이터-레이크-서비스-aws&quot;&gt;데이터 레이크 서비스 (AWS)&lt;/h2&gt;





















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;컴포넌트&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;서비스&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-s3|S3]], [[aws-s3-glacier|S3 Glacier]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;카탈로그&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|AWS Glue Data Catalog]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ETL&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-glue|Glue]] Spark, EMR, Databricks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;거버넌스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-lake-formation|Lake Formation]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;쿼리 (SQL)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-athena|Athena]], [[aws-redshift-spectrum|Redshift Spectrum]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;쿼리 (Spark)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-emr|EMR]], Glue Spark&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;인제스션&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Kinesis, [[aws-glue|Glue]] CDC, DMS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;BI&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;QuickSight&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ML&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SageMaker&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;PII 감지&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Macie&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;관리형 Iceberg&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;S3 Tables (2024+)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;원본만 쌓고 계층/카탈로그 없음&lt;/strong&gt; = data swamp. 처음부터 zone (Bronze/Silver/Gold) + [[aws-glue|Glue Catalog]] 등록을 강제하는 파이프라인 규약 필요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;CSV / JSON 을 그대로 유지&lt;/strong&gt; = 다운스트림 ([[aws-athena|Athena]], [[aws-redshift-spectrum|Spectrum]]) 이 매번 10-100배 스캔량. Silver 계층으로 승격할 때 반드시 [[apache-parquet|Parquet]] 로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;PII 무분별 저장&lt;/strong&gt; = 규제 위반 (GDPR, KISA). 로드 전 masking / tokenization, Macie 로 지속 탐지, Lake Formation 로 컬럼 접근 제어.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Small files 문제 를 무시&lt;/strong&gt; = 파티션 세분화 + 스트리밍 flush 로 수백만 파일 = 성능/비용 폭탄. Compaction job 필수, 또는 Iceberg auto-compact.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;트랜잭션 없이 UPDATE/DELETE 필요&lt;/strong&gt; = 원본 파일을 다시 쓰다가 partial write / 동시성 문제. Iceberg / Delta 로 승격.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;접근 제어를 IAM/버킷 정책만으로&lt;/strong&gt; = 컬럼/row 단위 제어 불가. [[aws-lake-formation|Lake Formation]] 로 세분화.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;“Data Lake vs Warehouse” 이분법 오류&lt;/strong&gt;. 현대는 lakehouse 로 병합. [[data-warehouse|DW]] 는 Gold 계층의 특수 형태로 볼 수 있음.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;lineage 없음&lt;/strong&gt; = 컬럼 값이 어디서 왔는지 추적 불가 -&gt; 사고 시 원인 파악 불가. [[aws-glue|Glue Catalog]] + dbt docs / OpenLineage / Marquez.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[data-warehouse|Data Warehouse]] - 정제된 대응&lt;/li&gt;
&lt;li&gt;[[etl|ETL / ELT]] - 데이터 파이프라인&lt;/li&gt;
&lt;li&gt;[[apache-parquet|Apache Parquet]] - 표준 저장 포맷&lt;/li&gt;
&lt;li&gt;[[aws-s3|AWS S3]] - 저장 백엔드&lt;/li&gt;
&lt;li&gt;[[aws-s3-glacier|S3 Glacier]] - Bronze 아카이빙&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - 카탈로그 + ETL&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - SQL 쿼리 엔진&lt;/li&gt;
&lt;li&gt;[[aws-redshift-spectrum|Redshift Spectrum]] - Redshift 에서 lake 쿼리&lt;/li&gt;
&lt;li&gt;[[aws-emr|Amazon EMR]] - Spark/Presto/Hive 클러스터&lt;/li&gt;
&lt;li&gt;[[aws-lake-formation|AWS Lake Formation]] - 거버넌스&lt;/li&gt;
&lt;li&gt;[[aws-redshift|Amazon Redshift]] - DW 대안&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>data-lake</category><category>s3</category><category>big-data</category><category>storage</category><category>analytics</category><author>koa (김신건)</author></item><item><title>데이터 웨어하우스</title><link>https://shinkeonkim.com/wiki/data-engineering/data-warehouse/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/data-engineering/data-warehouse/</guid><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;데이터 웨어하우스&lt;/strong&gt; (Data Warehouse, DW) 는 &lt;em&gt;여러 운영 시스템에서 흘러 들어온 이력 데이터를 통합해, 대규모 분석 쿼리를 빠르게 실행하도록 최적화된 중앙 저장소&lt;/em&gt;. 트랜잭션 처리 (OLTP) 가 아니라 &lt;em&gt;의사결정 지원&lt;/em&gt; (OLAP, BI, 리포팅, ML 특징 엔지니어링) 이 목적.&lt;/p&gt;
&lt;p&gt;Bill Inmon (1990) 정의: &lt;em&gt;주제 지향 (subject-oriented), 통합 (integrated), 시변 (time-variant), 비휘발성 (non-volatile) 데이터 컬렉션&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;p&gt;운영 DB ([[postgresql|PostgreSQL]], [[aws-rds|RDS]], MySQL) 를 그대로 분석에 쓰면 문제가 쌓임:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OLTP 최적화&lt;/strong&gt;: row-based 저장, 인덱스는 point-lookup 위주 -&gt; &lt;code&gt;SELECT SUM(x) FROM huge_table GROUP BY y&lt;/code&gt; 가 초 단위 -&gt; 시간 단위로 느려짐&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자원 경합&lt;/strong&gt;: 분석 쿼리가 트랜잭션을 락, latency spike&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;스키마 분산&lt;/strong&gt;: 서비스별 DB 가 나뉘어 있어 join 이 불가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이력 부족&lt;/strong&gt;: 운영 DB 는 최신 상태만, 과거 시점 재구성이 안 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DW 는 &lt;em&gt;분석 전용&lt;/em&gt; 이라 다음을 뒤집음:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;컬럼형 저장&lt;/em&gt; (필요한 컬럼만 스캔)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;압축&lt;/em&gt; (컬럼 값이 비슷 -&gt; 5-10배 압축)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;병렬 실행 (MPP)&lt;/em&gt; (수십/수백 노드로 분산 스캔)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;append/bulk load 위주&lt;/em&gt; (row-level update 는 거의 없음)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;스키마 통합 + 시계열 보존&lt;/em&gt; (fact + dimension 모델)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;oltp-vs-olap&quot;&gt;OLTP vs OLAP&lt;/h2&gt;




























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;OLTP&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;OLAP (DW)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;목적&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;트랜잭션 처리&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;분석 / BI / ML&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장 형식&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row-based&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Column-based&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;쿼리 형태&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소량 row 조회/갱신&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대량 aggregation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;동시성&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;수천 사용자 point 쿼리&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;수십 분석가 heavy 쿼리&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;정규화&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;3NF (중복 최소화)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Denormalized (join 최소화)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;인덱스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;B-tree point-lookup&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Zone map, min-max, columnar&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;데이터 신선도&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실시간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;분/시간/일 단위 (배치)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;변경 빈도&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Row 단위 UPDATE 자주&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Bulk INSERT/APPEND 위주&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;트랜잭션&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID 필수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;배치 로드 후 read-only 가까움&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;대표 예&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[postgresql&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Postgres]], MySQL, [[dynamodb|DynamoDB]]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;아키텍처-계층&quot;&gt;아키텍처 계층&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Sources[&quot;소스 (OLTP, 이벤트)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        RDS[(&quot;RDS/Aurora&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Kafka[Kafka/Kinesis]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SaaS[&quot;SaaS API&amp;#x3C;br/&gt;(Stripe, Salesforce)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Logs[Application Logs]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sources --&gt;|&quot;Extract + Load&quot;| Raw&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Warehouse[&quot;Data Warehouse&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Raw[&quot;Raw / Landing&amp;#x3C;br/&gt;(원본 그대로)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Staging[&quot;Staging&amp;#x3C;br/&gt;(타입 정리)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Marts[&quot;Data Marts&amp;#x3C;br/&gt;(dim + fact)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Raw --&gt; Staging&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Staging --&gt; Marts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Marts --&gt;|&quot;SQL / BI&quot;| BI[BI / 대시보드]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Marts --&gt;|&quot;Feature Store&quot;| ML[ML 학습]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Marts --&gt;|&quot;Reverse ETL&quot;| Ops[&quot;운영 시스템&amp;#x3C;br/&gt;(활성화)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Raw / Landing&lt;/strong&gt;: 소스 그대로. 재처리 가능하도록 원본 보존&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Staging&lt;/strong&gt;: 타입 캐스팅, dedup, timestamp 표준화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Marts / Curated&lt;/strong&gt;: 비즈니스 도메인별 dimension + fact 테이블. 소비자가 직접 쿼리&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;데이터-모델링-방법론&quot;&gt;데이터 모델링 방법론&lt;/h2&gt;
&lt;h3 id=&quot;kimball-dimensional--star-schema&quot;&gt;Kimball (Dimensional / Star Schema)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;업무 프로세스 중심&lt;/em&gt; 으로 fact 테이블 + 주변 dimension 테이블. Bottom-up.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       dim_date            dim_product&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          │                     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          └─────► fact_sales ◄──┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     ▼&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                dim_customer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     ▼&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                 dim_store&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fact table&lt;/strong&gt;: 이벤트/측정 (수량, 금액). 좁고 길다 (많은 row).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dimension table&lt;/strong&gt;: 컨텍스트 (누가, 무엇을, 언제, 어디서). 넓고 짧다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grain&lt;/strong&gt;: fact 한 행이 무엇을 의미하는지 (한 주문 line, 한 클릭 등) 명확히 정의.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SCD (Slowly Changing Dimension)&lt;/strong&gt;: Type 1 (overwrite), Type 2 (버전), Type 3 (이전 값 컬럼) 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;쉬운 SQL, BI 도구 친화&lt;/em&gt; -&gt; 사실상 산업 표준.&lt;/p&gt;
&lt;h3 id=&quot;inmon-corporate-information-factory&quot;&gt;Inmon (Corporate Information Factory)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;전사 통합 3NF 모델 (EDW)&lt;/em&gt; 을 먼저 만들고, 그 위에 부서별 mart 를 파생. Top-down.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;엄격한 통합&lt;/strong&gt;: 회사 전체 개념 하나의 스키마&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;느린 구축&lt;/strong&gt;: 몇 년 걸림&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;일관성 최우선&lt;/strong&gt;: 규제 산업 (금융/보험) 에 어울림&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;data-vault-20&quot;&gt;Data Vault 2.0&lt;/h3&gt;
&lt;p&gt;Hub (business key) + Link (관계) + Satellite (속성 변경 이력) 3 컴포넌트.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;소스 시스템 변화에 강함&lt;/li&gt;
&lt;li&gt;감사/이력 추적이 first-class&lt;/li&gt;
&lt;li&gt;쿼리는 복잡 -&gt; 소비 계층에서 star schema 로 pivot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;현대 실무&lt;/strong&gt;: raw/staging 은 Data Vault 스타일, 소비 계층은 Kimball star schema 조합이 많음.&lt;/p&gt;
&lt;h2 id=&quot;dw-vs-data-lake-vs-data-lakehouse&quot;&gt;DW vs Data Lake vs Data Lakehouse&lt;/h2&gt;



























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Data Warehouse&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Data Lake&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Data Lakehouse&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;저장&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;구조화 (컬럼형)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원본 파일 ([[apache-parquet]], JSON, CSV)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;원본 파일 + 트랜잭션 메타&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;스키마&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Schema-on-write&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Schema-on-read&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;둘 다&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;엔진&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자체 SQL (Redshift, BigQuery)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다양 (Athena, Spark)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Delta Lake, Iceberg, Hudi&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;워크로드&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BI, SQL 분석&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ML, batch, 로그 원본&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BI + ML 통합&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;저장 비쌈, 쿼리 저렴&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;저장 매우 저렴 ([[aws-s3|S3]]), 쿼리 유료&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;트랜잭션&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ACID (Iceberg/Delta/Hudi)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;거버넌스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;성숙&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;어려움 (“data swamp”)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;개선됨&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;대표&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[aws-redshift|Redshift]], Snowflake, BigQuery&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;S3 + [[aws-athena|Athena]] + [[aws-glue|Glue]]&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Databricks, Iceberg on S3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Lakehouse&lt;/em&gt; 는 lake 의 저비용 + warehouse 의 트랜잭션/거버넌스를 결합하려는 시도. 2020 이후 표준 방향.&lt;/p&gt;
&lt;h2 id=&quot;주요-관리형-데이터-웨어하우스&quot;&gt;주요 관리형 데이터 웨어하우스&lt;/h2&gt;





















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;제품&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;강점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;약점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[aws-redshift|Amazon Redshift]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;PostgreSQL 기반 MPP, RA3 + Serverless&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AWS 통합, [[aws-redshift-spectrum|Spectrum]], [[aws-glue|Glue]] 연계&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AWS 락인&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Google BigQuery&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Serverless, Dremel 기반&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;인프라 걱정 없음, 스토리지/쿼리 분리 과금&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GCP 락인&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Multi-cloud, virtual warehouse&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;UX 우수, 데이터 공유&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;벤더 비용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Azure Synapse&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Azure 통합&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Power BI 연계&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;성숙도&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Databricks SQL&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Delta Lake + Photon&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Lakehouse, ML 통합&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;세팅 필요&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ClickHouse&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스 컬럼 DB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;초고속, 셀프 호스팅&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;관리 부담&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DuckDB&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;임베디드 OLAP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;로컬/노트북 분석&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단일 노드&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;컬럼형-저장이-빠른-이유&quot;&gt;컬럼형 저장이 빠른 이유&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Row-based:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  [row1: col1, col2, col3, col4, ..., col50]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  [row2: col1, col2, col3, col4, ..., col50]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  → SELECT AVG(col3) 도 전체 row 를 읽어야 함&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Column-based:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  [col1: v1, v2, v3, ..., vN]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  [col2: v1, v2, v3, ..., vN]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  [col3: v1, v2, v3, ..., vN]    ← 이 컬럼만 스캔&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  → I/O 가 필요한 컬럼만&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;추가 이득&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;압축&lt;/strong&gt;: 같은 컬럼 값의 카디널리티가 낮음 -&gt; RLE, Dictionary, Delta 등으로 5-10배 압축&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SIMD&lt;/strong&gt;: 같은 타입이 연속 -&gt; CPU 벡터 명령&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zone map / min-max&lt;/strong&gt;: 블록 skip&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Late materialization&lt;/strong&gt;: 필터 통과한 row 만 실제 조합&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자세히: [[apache-parquet]] (파일 포맷), [[aws-redshift|Redshift]] (엔진 사례).&lt;/p&gt;
&lt;h2 id=&quot;로딩-패턴&quot;&gt;로딩 패턴&lt;/h2&gt;
&lt;h3 id=&quot;배치-etl--etlelt&quot;&gt;배치 [[etl]] / [[etl|ELT]]&lt;/h3&gt;
&lt;p&gt;가장 흔함. 시간/일 단위 배치.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Source DB] ──dump──&gt; [S3 raw] ──[aws-glue|Glue] transform──&gt; [DW]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;cdc-change-data-capture&quot;&gt;CDC (Change Data Capture)&lt;/h3&gt;
&lt;p&gt;소스 DB 의 WAL/binlog 을 스트림으로 수신, 거의 실시간 반영.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debezium, AWS DMS, [[aws-redshift|Redshift]] Zero-ETL&lt;/li&gt;
&lt;li&gt;지연: 초 단위&lt;/li&gt;
&lt;li&gt;부하: 소스 DB 에 로그 리더 프로세스&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;스트리밍-인제스션&quot;&gt;스트리밍 인제스션&lt;/h3&gt;
&lt;p&gt;Kafka, Kinesis 에서 직접 DW 로 append.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[aws-redshift|Redshift]] Streaming Ingestion, Snowpipe Streaming, BigQuery Storage Write API&lt;/li&gt;
&lt;li&gt;Materialized view 로 auto-aggregate&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;reverse-etl&quot;&gt;Reverse ETL&lt;/h3&gt;
&lt;p&gt;DW 에서 계산된 지표를 다시 SaaS/운영 시스템으로 push (Hightouch, Census).&lt;/p&gt;
&lt;h2 id=&quot;성능-최적화의-축&quot;&gt;성능 최적화의 축&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;파티셔닝 / 정렬 키&lt;/strong&gt;: filter predicate 컬럼으로 물리 분리 -&gt; 블록 skip&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분산 키&lt;/strong&gt; (MPP): join 키가 같은 노드에 -&gt; shuffle 제거&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일 포맷&lt;/strong&gt;: [[apache-parquet]] / ORC (컬럼형, 통계, 압축)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일 크기&lt;/strong&gt;: 128 MB ~ 1 GB 권장. 작은 파일 수천 개 = &lt;em&gt;small files problem&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;압축 encoding&lt;/strong&gt;: 컬럼별 특성에 맞는 코덱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Materialized view / pre-aggregation&lt;/strong&gt;: 반복 쿼리를 미리 계산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Result cache&lt;/strong&gt;: 같은 쿼리 결과 재사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concurrency scaling&lt;/strong&gt;: 읽기 부하 시 클러스터 자동 확장&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;데이터-품질--거버넌스&quot;&gt;데이터 품질 &amp;#x26; 거버넌스&lt;/h2&gt;
&lt;p&gt;DW 는 “회사의 단일 진실 (Single Source of Truth)” 목표. 품질/거버넌스 없으면 &lt;em&gt;data swamp&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Data contracts&lt;/strong&gt;: 소스와 target 간 스키마/의미 합의&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lineage&lt;/strong&gt;: 컬럼 값이 어디서 왔는지 추적 ([[aws-glue|Glue]] Data Catalog, dbt docs)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt;: dbt test, Great Expectations, Soda 로 not null / unique / accepted values 검증&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Access control&lt;/strong&gt;: 컬럼/row 단위 접근 (Redshift RLS, BigQuery column-level security)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PII 관리&lt;/strong&gt;: KMS 암호화, 마스킹, tokenization&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost governance&lt;/strong&gt;: 사용자별 쿼리 한도, workgroup 예산 알림&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;DW 를 운영 DB 로 쓰면 재앙&lt;/strong&gt;. Row-level UPDATE/DELETE 가 느리고 비쌈. 트랜잭션 워크로드는 [[postgresql|Postgres]] 같은 OLTP 로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;&lt;code&gt;INSERT&lt;/code&gt; 한 행씩&lt;/strong&gt; = MPP 의 최악의 워크로드. 항상 bulk load (COPY, [[apache-parquet|Parquet]] batch).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;정규화 그대로 이식&lt;/strong&gt; = star schema 없이 3NF 를 DW 에 넣으면 join 지옥. Kimball 스타일로 denormalize.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;schema-on-read 만 믿지 말 것&lt;/strong&gt;. Data lake 에 원본만 넣고 스키마 안 잡으면 시간 지날수록 아무도 못 씀. Contract + validation 필수.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;비용 폭탄 3대 원인&lt;/strong&gt;: &lt;code&gt;SELECT *&lt;/code&gt;, 파티션 없는 스캔, 작은 파일 수천 개. [[aws-athena|Athena]] / [[aws-redshift-spectrum|Spectrum]] 은 스캔량 과금이라 특히.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;DW 는 단일 진실이 아니라 “합의된 진실”&lt;/strong&gt; 이다. 소스 시스템의 semantics 를 명시적으로 문서화하지 않으면 지표가 팀마다 달라짐.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[apache-parquet]] - DW/lake 의 사실상 표준 파일 포맷&lt;/li&gt;
&lt;li&gt;[[etl]] - DW 로 데이터를 넣는 파이프라인&lt;/li&gt;
&lt;li&gt;[[aws-redshift|AWS Redshift]] - AWS 관리형 DW&lt;/li&gt;
&lt;li&gt;[[aws-redshift-spectrum|Redshift Spectrum]] - S3 데이터 직접 쿼리&lt;/li&gt;
&lt;li&gt;[[aws-athena|Amazon Athena]] - Serverless 쿼리 엔진&lt;/li&gt;
&lt;li&gt;[[aws-glue|AWS Glue]] - ETL + Data Catalog&lt;/li&gt;
&lt;li&gt;[[aws-s3|AWS S3]] - Data lake 저장소&lt;/li&gt;
&lt;li&gt;[[aws-s3-glacier|S3 Glacier]] - DW 콜드 아카이빙&lt;/li&gt;
&lt;li&gt;[[postgresql|PostgreSQL]] - OLTP 대비 (Redshift 원류)&lt;/li&gt;
&lt;li&gt;[[sharding-vs-partitioning|샤딩 vs 파티셔닝]] - 분산 저장 원리&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>data-engineering</category><category>data-warehouse</category><category>olap</category><category>analytics</category><category>dimensional-modeling</category><author>koa (김신건)</author></item></channel></rss>