引言

在數據倉庫(Data Warehouse)設計中,事實表(Fact Table)和 事實寬表(Wide Fact Table)是兩種常見的存儲度量數據的表格。它們在結構、查詢效率、存儲方式等方面有所不同,選擇合適的設計模式對於提高查詢性能、減少存儲開銷以及滿足業務需求至關重要。本文將詳細介紹事實表與事實寬表的定義、區別及應用場景,並通過實際的 SQL 示例幫助您更好地理解這兩種設計模式。


1. 事實表(Fact Table)概述

什麼是事實表?

事實表是數據倉庫中的核心組成部分,它存儲了關於某一特定業務過程的度量數據。例如,銷售事實表可能記錄每一筆銷售的銷售額、數量、折扣等信息。事實表通常與維度表通過外鍵進行連接,維度表則提供了描述性的信息(如產品、客户、時間、地區等)。

事實表結構:

  • 度量數據(Measures):事實表的核心內容是度量數據,如銷售額、利潤、訂單數量等。這些度量數據是我們進行分析的主要對象。
  • 外鍵(Foreign Keys):事實表通過外鍵與維度表關聯。例如,ProductIDCustomerIDDateID 等外鍵將事實表與產品維度表、客户維度表、日期維度表等聯繫起來。
  • 粒度(Granularity):事實表的粒度指的是每條記錄的詳細程度。例如,銷售事實表的粒度可能是按“每筆銷售”記錄,或者按“每日銷售彙總”記錄。

事實表的例子:

假設我們有一個銷售事實表 SalesFact,記錄了每筆銷售的銷售金額和銷售數量,並與多個維度表連接:

SalesID

ProductID

CustomerID

DateID

SalesAmount

QuantitySold

1

101

201

20230101

500

10

2

102

202

20230101

300

5

3

101

203

20230102

450

8

  • 外鍵ProductIDCustomerIDDateID 連接到相應的維度表,提供關於產品、客户和日期的信息。
  • 度量數據SalesAmountQuantitySold 是事實數據,反映了銷售過程中的重要度量。

查詢示例:

假設我們要查詢 2023 年第一季度每個產品類別的總銷售額,SQL 查詢可以如下編寫:

SELECT 
    p.Category AS ProductCategory,
    SUM(s.SalesAmount) AS TotalSales
FROM 
    SalesFact s
JOIN 
    ProductDim p ON s.ProductID = p.ProductID
JOIN 
    DateDim d ON s.DateID = d.DateID
WHERE 
    d.Year = 2023 AND d.Quarter = 1
GROUP BY 
    p.Category
ORDER BY 
    TotalSales DESC;

解析:

  • SalesFact 表記錄了每筆銷售的事實數據,ProductDim 表提供了產品的類別信息,DateDim 表提供了日期的年份和季度信息。
  • 查詢結果將按產品類別彙總銷售額,返回 2023 年第一季度的銷售排名。

優缺點:

優點:

  1. 結構簡潔:事實表僅存儲外鍵和度量數據,易於理解和維護。
  2. 適合複雜查詢:適合需要多維分析和彙總的複雜查詢,尤其是 OLAP 查詢(聯機分析處理)。
  3. 靈活性高:支持快速擴展和修改,新增維度或度量時修改成本較低。

缺點:

  1. 查詢時需要聯接:事實表通常需要與多個維度表進行聯接,查詢複雜度較高。
  2. 存儲較為分散:由於維度數據存儲在維度表中,查詢時需要多次訪問不同表,可能影響查詢性能。

2. 事實寬表(Wide Fact Table)概述

什麼是事實寬表?

事實寬表是事實表的一種變體,它將所有維度信息和度量數據合併到一張表中,而不是通過外鍵與多個維度表進行關聯。簡單來説,事實寬表是“寬”的表,通常包含大量的列,其中包括維度信息和度量數據。

事實寬表結構:

  • 所有維度信息存儲在同一表中:在事實寬表中,所有的維度信息(如產品名稱、客户信息、時間等)都直接存儲在表中,而不是通過外鍵引用維度表。
  • 寬表列數多:因為每個銷售記錄都包含了所有維度的數據,表格的列數可能非常多,因此稱為“寬表”。
  • 沒有外鍵:事實寬表中不再使用外鍵與維度表關聯,維度信息存儲為常規列。

事實寬表的例子:

假設我們有一個寬表 SalesWide,將維度信息和度量數據直接存儲在同一張表中:

SalesID

ProductName

ProductCategory

CustomerName

Date

Region

SalesAmount

QuantitySold

1

Laptop

Electronics

Alice

2023-01-01

North

500

10

2

Smartphone

Electronics

Bob

2023-01-01

Europe

300

5

3

Laptop

Electronics

Charlie

2023-01-02

Asia

450

8

  • 維度信息存儲在表中ProductNameProductCategoryCustomerNameDateRegion 等列直接存儲在表中,而不是通過外鍵連接其他維度表。
  • 度量數據SalesAmountQuantitySold 是度量數據。

查詢示例:

查詢 2023 年第一季度每個產品類別的總銷售額,可以直接從 SalesWide 表中獲取:

SELECT 
    ProductCategory, 
    SUM(SalesAmount) AS TotalSales
FROM 
    SalesWide
WHERE 
    Date BETWEEN '2023-01-01' AND '2023-03-31'
GROUP BY 
    ProductCategory
ORDER BY 
    TotalSales DESC;

解析:

  • 因為所有的維度數據都已經存儲在 SalesWide 表中,查詢時不需要進行聯接。
  • 該查詢非常高效,適合簡單的分析場景,但隨着數據量的增大,查詢性能可能會受到影響。

優缺點:

優點:

  1. 查詢高效:由於所有數據都存儲在同一張表中,查詢時不需要進行表聯接,查詢速度較快。
  2. 結構簡單:維度信息和度量數據在同一張表中,數據模型簡單,易於維護。
  3. 適用於小規模數據:適合數據量不大且查詢結構簡單的場景。

缺點:

  1. 數據冗餘:每條記錄都存儲了大量的維度信息,導致數據冗餘,增加了存儲成本。
  2. 擴展性差:隨着維度數量的增加,寬表會變得非常龐大,查詢性能可能會下降,且表結構不易擴展。
  3. 不適合複雜查詢:當維度結構複雜時,寬表不適合進行多維分析,且隨着數據量增大,查詢效率可能降低。

3. 事實表與事實寬表的對比

特性

事實表(Fact Table)

事實寬表(Wide Fact Table)

結構

事實表存儲外鍵,度量數據簡潔

所有維度信息直接存儲在同一表中,列數多

查詢效率

查詢時需要進行表聯接

查詢無需聯接,效率較高

存儲效率

存儲空間高效,避免冗餘

存儲冗餘,數據量大時存儲空間浪費較大

擴展性

具有較好的擴展性,支持新增維度

隨着維度增加,擴展性差

適用場景

大規模數據倉庫、多維分析

小規模數據、簡單分析


總結

  • 事實表適用於需要高效、多維分析的場景,支持複雜查詢和大規模數據倉庫設計,能夠提供較好的查詢性能和擴展性。
  • 事實寬表適用於查詢簡單且數據量較小的場景,它的查詢效率較高,設計簡單,但隨着數據量的增加,可能會出現存儲冗餘和性能下降等問題。

在實際應用中,選擇 事實表 還是 事實寬表 需要根據具體的業務需求、數據量以及查詢複雜度來決定。對於數據倉庫的複雜查詢和多維分析,事實表是更合適的選擇;而對於簡單查詢和小規模數據分析,事實寬表則可能更高效。