把資料變好用:查詢、建模與轉換,讀《Fundamentals of Data Engineering》Ch.8
· tech
#data-engineering#book-notes#data-modeling
資料擷取進來、存好了,接下來的問題是:怎麼把它變成真正好用的東西? 這章給了三支柱 —— 查詢(Query)、建模(Modeling)、轉換(Transformation)。它們合起來,把「一堆原始資料」變成「業務問得動、查得快的模型」。其中建模是最被工程師低估、卻最關鍵的一支,這篇的重量也放在那。
查詢:SQL 是通用語,optimizer 幫你幹活
查詢的核心是 SQL —— 你用宣告式的方式說「我要什麼」,查詢優化器(query optimizer) 幫你決定「怎麼拿」(要不要用索引、join 順序、要掃多少)。所以寫查詢的功力,一半在於別擋住優化器、也別逼它做蠢事:
| 常見地雷 | 該做的 |
|---|---|
| 全表掃描 | 用分區 / 索引 / 欄式,只讀要的 |
SELECT * | 只取需要的欄(欄式倉儲尤其有感) |
| 亂 join 一堆大表 | join 是最貴的一步(見 shuffle),先過濾再 join |
| 在 where 對欄位包函式 | 讓條件能被 predicate pushdown 推到最底層 |
一句話:SQL 是宣告式的,但效能不是自動的 —— 你要給優化器一個好發揮的環境。
建模:把「業務」翻譯成「表」
建模就是決定資料長什麼結構。為什麼重要?因為結構決定了查詢好不好寫、跑不跑得快、以及非工程師能不能自己查。第一個要面對的取捨,是正規化到什麼程度:
OLTP 愛正規化(少重複、寫入一致),分析卻常反過來 —— 因為 欄式儲存又便宜又快,重複不心疼,少一次 join 卻省很多。這是 Ch.5講的「OLTP 別直接拿來分析」在建模層的延伸。
分析建模的經典:星狀綱要(Star Schema)
Kimball 的維度建模是分析界最通用的一招:把資料分成兩種表 —— 事實表(Fact) 記錄可加總的度量、維度表(Dimension) 描述情境:
星狀綱要好用,是因為它把「要算什麼(事實)」和「用什麼角度切(維度)」分乾淨。想看「各地區、各月的銷售額」?join 門市與日期兩張維度、對金額加總就好 —— 連非工程師都能照著切。書也提到其他學派,各有立場:
| 學派 | 一句話 |
|---|---|
| Kimball | 由下而上、維度建模、星狀綱要(最通用) |
| Inmon | 由上而下、先建正規化的企業級倉儲,再切 data mart |
| Data Vault | hub / link / satellite,為可追溯與演進而生 |
| 寬表(One Big Table) | 乾脆全攤平成一張大表,靠欄式引擎硬吃 |
不用背哪個「對」——它們是不同取捨:Kimball 好懂好自助、Inmon 重治理、Data Vault 重可追溯、寬表重查詢速度。
轉換:把原始資料變成模型,而且 T 的位置變了
有了模型的藍圖,轉換負責真的把原始資料塑形成它。這裡最大的變化是 ETL → ELT:
- ETL:先轉換,再載入倉儲(倉儲貴,只放乾淨資料)。
- ELT:先原封不動載入,再在倉儲裡用 SQL 轉換(儲存便宜、倉儲夠強,乾脆讓它扛)。
ELT 會贏,根源還是 運算與儲存分離、儲存變便宜:反正先存下來不痛,轉換就交給倉儲的 SQL。這也是 Medallion 分層和 dbt 這類工具的底層前提 —— 在倉儲裡用一層層 SQL,把 Bronze 原始資料逐步轉成 Gold 模型。轉換也不只批次:串流轉換(見 Structured Streaming)在資料流過時就邊算邊塑形。至於 view vs 物化(materialized),是另一個典型取捨:view 每次查即時算(省空間、慢),物化預先算好存起來(快、佔空間、要刷新)。
反思
建模是把業務翻成表,這是最被低估的軟實力
寫這章我最有感的是:建模的難點根本不在技術,在懂業務。 星狀綱要漂亮,不是因為它技術多炫,而是它逼你想清楚「這門生意的度量是什麼、要用哪些角度切」。我看過太多資料專案卡住,不是引擎不夠快,是沒人把業務問題翻成乾淨的模型 —— 表長得像後端的 OLTP schema,分析師每查一個數字都要 join 七張表、還常算錯。把資料建得讓非工程師都能自助查,是我認為資料團隊最該練、卻最少人練的一項能力。
我偏好 ELT + 分層 + dbt,而且理由一路連得起來
這幾篇下來,我的立場越來越一致:先把原始資料落進便宜的儲存(ELT 的 L),再用 SQL 一層層轉(T)。 這不是趕流行 —— 它一路接得回 運算儲存分離、Medallion 的 Bronze 不可變、可重播。用 SQL 而不是一堆散落的腳本做轉換,好處是版本控管、可測試、人人看得懂(dbt 把這套做成了工程規範)。ETL 不是錯,但在「儲存便宜、倉儲夠強」的今天,ELT 是我的預設。
別把 OLTP 的正規化直覺,帶到分析
這是我年輕時踩過的坑:後端出身,看到重複資料就渾身不對勁,於是把分析表也正規化得漂漂亮亮 —— 結果每張報表都在狂 join,慢得要命。後來才想通:欄式倉儲上,重複的成本很低,少一次 join 的收益很高。 分析建模該問的不是「夠不夠正規化」,而是「查詢好不好寫、跑不跑得快」。這跟 Ch.4那句「每個選擇都是取捨、看工作負載選邊」一模一樣 —— 正規化是給寫入用的美德,分析要的是另一套。