圖解事實表、維度表與星形架構:數據中台讓資料一目瞭然的設計

事實表存數字與事件,維度表存看資料的角度,星形架構把它們組成最適合分析的模型。用小明買咖啡豆的一筆訂單,圖解數據中台為什麼能讓資料一目瞭然,以及它與正規化、反正規化的差別。

分享
圖解事實表、維度表與星形架構:數據中台讓資料一目瞭然的設計

上一篇文章中,我們聊到了資料庫的「正規化」與「反正規化」,以及資料管理員與資料取用者之間的兩難。

為了讓資料取用者不用再跨越五六張表找資料,數據中台的架構設計難道只能沿用正規化與反正規化?還是有更好的做法?

2025年我開始教 Power BI 的時候,接觸到了「事實表(Fact Table)」與「維度表(Dimension Table)」的設計。這讓我非常好奇:這跟傳統的正規化與反正規化又有什麼不同?

這篇文章,就讓我們來拆解這些讓資料分析師愛不釋手的魔法。

數據分析的兩大主角:事實表與維度表

1. 事實表(Fact Table):記錄「發生了什麼事」

事實表是分析模型中用來記錄「事件」或「數字指標」的表。它通常回答:發生了什麼事?發生在什麼時間?數量、金額、次數是多少?

簡單來說:事實表 = 業務事件 + 可衡量數字。

例如,小明 8 月 15 日在「台北信義店」買了 2 包咖啡豆,共 1,000 元——這筆訂單寫入「銷售事實表」會這樣呈現,包含業務計算需要加總計算的指標是「數量」與「金額」,而其他的 ID 則是拿來連到維度表的鑰匙(Key):

order_iddate_idcustomer_idproduct_idstore_idquantityamount
O00120260815C001P001S00121000

表格裡的 ID 就是「鑰匙(Key)」的意思:兩張表只要共用同一個編號,就能接起來。拿著 customer_id = C001 到客戶維度表,找到編號相同的那一列,兩張表就對上了——像拿號碼牌領餐一樣,資料庫的 JOIN 做的就是這件事。

對照上面這一列:C001 查客戶維度表是小明、P001 查商品維度表是咖啡豆、S001 查門市維度表是台北信義店;quantity 是購買數量 2 包,amount 是總金額 1,000 元(2 包 × 單價 500 元)。

2. 維度表(Dimension Table):描述「事件的背景」

維度表是用來描述事實的背景資料。它通常回答:這是誰?什麼商品?哪一天?哪個地點?

簡單來說:維度表 = 看資料的角度。

例如:

  • 客戶維度表: 告訴我們客戶的名字、性別、城市、會員等級。(C001 → 小明:台北、金卡會員)
  • 商品維度表: 告訴我們商品的名稱、類別、品牌。(P001 → 咖啡豆,食品類)
  • 日期維度表: 告訴我們某個日期對應的年份、月份、星期幾。(20260815 → 2026 年 8 月、星期六)

其中「日期維度」最常讓人疑惑:日期本身不就是資訊了嗎,為什麼還要一張表?因為分析常用的「年、季、月、星期幾、是否假日」,如果每次都讓每個人自己從日期推算,算法可能不一樣——光「第幾季」就有日曆年度和會計年度兩種算法。先算好、放進維度表,全公司查出來的答案就是同一個。

日期維度表實際長這樣(小明那筆 20260815 就落在第二列):

date_id日期星期幾是否假日
202608142026-08-1420268星期五
202608152026-08-1520268星期六
202701012027-01-0120271星期五是(元旦)

所以像「假日銷售 vs 平日銷售」這種分析,JOIN 這張表就有現成的「是否假日」欄位,不用每次現場寫判斷式。

當你想要問:「今年每個城市的銷售金額是多少?」

你的資料來源就會是:

  • 銷售金額: 來自「事實表」。(O001 的 1,000 元)
  • 今年: 來自「日期維度」。(20260815 → 2026 年)
  • 城市: 來自「客戶維度」或「門市維度」。(C001 → 小明住台北)

以小明那筆訂單來說:事實表拿出 1,000 元、日期維度認出「2026 年」、客戶維度認出「台北」——三個來源拼出答案的一列:2026 年・台北・1,000 元

一個問題三個資料來源:今年來自日期維度、城市來自客戶或門市維度、銷售金額來自事實表,拼出答案的一列 2026 年台北 1,000 元

什麼是「星形架構」?

星形架構(Star Schema)就是中間擺一張「事實表」,周圍連接著多張「維度表」。因為它的關聯圖看起來就像一顆星星,因而得名。

星形架構:中間放銷售事實表,四周連接日期、客戶、商品、門市四張維度表,關聯圖像一顆星星

等一下,事實表跟上一篇的「訂單明細表」是不是很像?

眼尖的你可能發現了:事實表裡也是一堆 ID 加上數量與金額,跟上一篇正規化拆出來的「訂單明細表」幾乎長得一模一樣,差別在哪?

先看正規化這邊。線上系統為了記錄交易細節,把小明這筆訂單拆成兩張表,並且記錄了單價與狀態:

表一:orders (訂單主檔)

記錄這筆訂單是「誰、在什麼時候、哪家店」買的,以及「有沒有付款」。

order_idorder_datecustomer_idstore_idstatus
O0012026-08-15C001S001paid

表二:order_items (訂單明細)

記錄這筆訂單「買了什麼、買幾個、當時單價多少」。

order_idproduct_idquantityunit_price
O001P0012500

注意:這兩張表裡都沒有「城市」。S001 是哪個城市的店、小明住在哪個城市,要再連到「門市表」與「客戶表」才查得到——這就是待會對照表裡「繼續拆下去」的意思。

同一筆訂單,到了星形架構的事實表長這樣——金額已經算好(2 包 × 500 元 = 1,000 元),而且只留下已付款的訂單:

order_iddate_idcustomer_idproduct_idstore_idquantityamount
O00120260815C001P001S00121000

這樣設計的巨大優勢:團隊用 BI 拉資料時,再也不用去碰原始的 orders 和 order_items,不用自己過濾出已付款(paid)的訂單,也不用擔心數量乘錯單價——因為數據中台的加工流程(實務上常用 dbt 這類工具)已經幫大家把資料「清洗乾淨、算出金額、並附上所有的維度鑰匙」了!

正規化的訂單明細表星形架構的事實表
為誰設計系統寫入用:一筆一筆新增、修改分析讀取用:整批加總、換角度切
資料進去之後會隨狀態更新(訂單改了就改)不再改動,事件一筆一筆往後追加
連出去的表繼續拆下去(客戶表再連到城市表)維度表刻意合成寬表,查詢一步到位
訂單明細表與事實表對比:正規化世界查小明在哪個城市買要 JOIN 三次,星形架構的客戶維度一步到位

真正的差別在兩張表身處的世界。正規化的世界裡,訂單明細表連出去的每張表都會繼續拆,想查「小明在哪個城市買的」,要一路 JOIN 三張表;星形架構的世界裡,維度表刻意反正規化成寬表,城市、區域通通放進客戶維度,查詢一步到位。

等等,維度表這樣「合」,不會踩到上一篇說的反正規化的坑(資料重複、要自己維護一致性)嗎?會,但代價可控:維度表通常不大(幾千個客戶,對比幾百萬筆交易),而且由中台統一維護一份,不是讓每個報表各自合表、各自出錯——這正是把「合」放到對的位置的意思。

所以星形架構不是第三種新魔法,而是把上一篇的兩難各放到對的位置:中間的事實表保持「拆」的細緻——每筆事件只存一次;四周的維度表選擇「合」的方便——描述資料一張裝齊。

這也正面回答了開頭的問題:數據中台不必在正規化與反正規化之間二選一。

數據中台的分層設計:五層架構

那實務上,資料會直接從來源系統一步跳進星形架構嗎?不會。一個成熟的數據中台,會把資料分層加工,每一層只負責一件事:

數據中台的五層設計:stage 原始保留層、int 標準化層、dim 維度層、fact 事實層、mart 應用市集層
  1. stage_ 原始保留層: 保留來源系統的資料原貌(如原始訂單 O001,狀態欄還是原始的 paid)。
  2. int_ 標準化層: 統一語意與規則,讓全公司說同一種話(例如把狀態 paid 統一成「已付款」)。
  3. dim_ 維度層: 存放看資料的角度(如 dim_customer:小明、台北、金卡)。
  4. fact_ 事實層: 存放訂單事件與金額,並連動維度的 Key(如 fact_sales:O001,2 包、1,000 元)。
  5. mart_ 應用市集層: 提供給報表、API、AI 靈活使用的寬表或資料產品(如「城市 × 月份銷售」寬表)。

細心的你可能注意到:上一篇聊的「快照」去哪了?快照進了中台之後要怎麼設計——歷史版本怎麼留、每天的狀態怎麼存——資訊量值得專文一篇,我們另開一篇好好講。

一句話總結:這些名詞到底差在哪?

這套「事實表+維度表」的家,傳統上叫 資料倉儲(Data Warehouse)數據中台則是在資料倉儲的基礎上,把資料當成全公司共用的產品來經營的一整套做法。本文談的模型設計兩者通用,所以下表把它們寫在一起。

名稱它在回答什麼?常見位置特性
正規化資料要不要拆乾淨?線上交易系統 (OLTP)減少重複,重視一致性
反正規化資料要不要合起來方便查?報表層、Mart、寬表查詢方便,可能有重複
事實表發生了什麼?數字是多少?資料倉儲/ 數據中台存事件與指標
維度表從哪些角度分析?資料倉儲/ 數據中台存描述與分類
星形架構事實與維度怎麼組?BI、資料倉儲分析層好查詢、好理解、好做報表
💡 核心觀念:

現在我們知道星形架構很適合做報表,但一定有人會問:「我直接從現在的線上系統撈資料不行嗎?為什麼要這麼麻煩再建一套數據中台和星形架構?」下一篇,我們再來分析這件事情。


延伸閱讀

如果你也走在自己的路上,歡迎訂閱《小穗步電子報》——我會把每一次的覺察與練習,寫成信寄給你。→ 訂閱小穗步電子報

Read more