iT邦幫忙

2025 iThome 鐵人賽

DAY 22
1
AI & Data

「知其然,更知其所以然:什麼是 Real-time (Streaming) Pipeline?從造輪子到 Flink 與 RisingWave」系列 第 22

【知其然,更知其所以然】Day 22: 大寬表設計與 OLAP 集成

  • 分享至 

  • xImage
  •  

經過前 21 天對流處理核心概念的深入理解,今天我們要進入一個全新的實務領域:如何用流處理技術支撐複雜的業務分析需求

當你的老闆要求「我想看到每個客戶的訂單金額趨勢,按照付款方式和配送地區分組」時,你會發現傳統的 OLTP 架構開始力不從心。這正是大寬表設計與 OLAP 引擎組合登場的時刻。

從 OLTP 到 OLAP:業務分析的架構演進

傳統 OLTP 架構的挑戰

在電商系統中,我們習慣用正規化的方式設計資料表:

傳統 OLTP 多表設計:

┌─────────────┐  ┌─────────────────┐  ┌─────────────┐
│   orders    │  │  order_details  │  │  customers  │
├─────────────┤  ├─────────────────┤  ├─────────────┤
│ order_id    │  │ order_id        │  │ customer_id │
│ customer_id │  │ product_id      │  │ name        │
│ order_date  │  │ quantity        │  │ city        │
│ status      │  │ price           │  │ age         │
└─────────────┘  └─────────────────┘  └─────────────┘

┌─────────────┐  ┌─────────────────┐
│  payments   │  │   deliveries    │
├─────────────┤  ├─────────────────┤
│ order_id    │  │ order_id        │
│ amount      │  │ address         │
│ method      │  │ delivery_date   │
│ paid_at     │  │ status          │
└─────────────┘  └─────────────────┘

當業務分析需求來臨時

-- 想要分析:客戶的訂單金額趨勢,按付款方式和地區分組
SELECT 
    c.city,
    p.method,
    DATE_TRUNC('month', o.order_date) as month,
    SUM(p.amount) as total_amount
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN payments p ON o.order_id = p.order_id
JOIN deliveries d ON o.order_id = d.order_id
WHERE o.order_date >= '2024-01-01'
GROUP BY c.city, p.method, DATE_TRUNC('month', o.order_date);

問題就來了

  • JOIN 開銷巨大:4 張表的關聯查詢,資料量大時效能急劇下降
  • 鎖定競爭:分析查詢會影響交易系統的效能
  • 擴展困難:每增加一個維度,JOIN 複雜度指數級增長
  • 實時性差:複雜查詢需要幾分鐘甚至更長時間

大寬表 + OLAP:現代分析架構的解決方案

核心思想:用空間換時間,將 JOIN 操作前移到數據寫入階段。

Wide Table Processing Pipeline:

OLTP Systems:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│  orders  │ │ details  │ │customers │ │ payments │ │deliveries│
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
     │            │            │            │            │
     │ CDC        │ CDC        │ CDC        │ CDC        │ CDC
Kafka▼            ▼            ▼            ▼            ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│  orders  │ │ details  │ │customers │ │ payments │ │deliveries│
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
     │            │            │            │            │
     └────────────┼────────────┼────────────┼────────────┘
                  │            │            │
                  └────────────┼────────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │    Flink SQL        │
                    │   Stream JOIN       │
                    └─────────────────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │       OLAP          │
                    └─────────────────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │        API          │
                    └─────────────────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │     Dashboard       │
                    └─────────────────────┘

查詢變得極簡

-- 同樣的業務需求,只需單表查詢
SELECT
    customer_city,
    payment_method,
    DATE_TRUNC('month', order_date) as month,
    SUM(payment_amount) as total_amount
FROM order_wide_table
WHERE order_date >= '2024-01-01'
GROUP BY customer_city, payment_method, DATE_TRUNC('month', order_date);

性能提升顯著

  • 查詢速度:從分鐘級降低到秒級
  • 併發能力:OLAP 引擎專為分析查詢優化
  • 資源隔離:分析不影響交易系統
  • 擴展性:水平擴展,支援 PB 級數據

Flink SQL 實戰

業務需求分析

重要提醒
本文所有程式碼皆為教學與概念演示用的 Flink SQL,可以幫助你理解並解決實際場景的問題,但這裡的程式碼需要根據實際環境調整,主要目的是用來講解大寬表構建的設計思路與核心概念。

假設我們要構建一個電商平台的實時分析系統,需要整合以下業務實體:

Flink SQL 建表 DDL

-- 訂單表
CREATE TABLE orders (
    ...
) WITH (
    'connector' = 'kafka',
    'topic' = 'orders'
);

-- 客戶表
CREATE TABLE customers (
    ...
) WITH (
    'connector' = 'kafka',
    'topic' = 'customers'
);

-- 訂單明細表
CREATE TABLE order_details (
    ...
) WITH (
    'connector' = 'kafka',
    'topic' = 'order_details'
);

-- 付款表
CREATE TABLE payments (
    ...
) WITH (
    'connector' = 'kafka',
    'topic' = 'payments'
);

-- 配送表
CREATE TABLE deliveries (
    ...
) WITH (
    'connector' = 'kafka',
    'topic' = 'deliveries'
);

大寬表 JOIN 邏輯

CREATE TABLE order_wide_table (
    ...
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://localhost:3306/analytics',
    'table-name' = 'order_wide_table'
);

一次性 JOIN 所有表

INSERT INTO order_wide_table
SELECT 
    ...
FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id
LEFT JOIN order_details od ON o.order_id = od.order_id
LEFT JOIN payments p ON o.order_id = p.order_id
LEFT JOIN deliveries d ON o.order_id = d.order_id;

總結

商業開發的核心:其實 Flink SQL 大寬表開發就這麼簡單 - 定義好各個 Kafka 源表,然後用一個 INSERT 語句 JOIN 所有相關表,最後輸出到 JDBC 目標表。核心邏輯非常直觀,這就是現代流處理框架的威力。

大寬表設計的價值

通過今天的探討,我們理解了為什麼現代數據架構選擇「大寬表 + OLAP」這個模式:

解決了什麼問題

  • 系統隔離:分析查詢不再影響交易系統的性能
  • 擴展性:水平擴展支援 PB 級數據分析

核心設計思想

  • 流處理前置:在數據寫入階段完成複雜的 JOIN 操作
  • 標準化架構:從 OLTP → CDC → Kafka → Flink → OLAP 的現代數據流

這種架構已經成為大型電商、金融、物聯網等行業的標準解決方案。當你的分析查詢開始變慢時,大寬表設計往往是最直接有效的解決方案。

Day 23 預告:進階流處理與多層架構設計

基礎的大寬表只是開始!在實際的商業場景中,有些需求會更進階:

  • 在 Streaming 階段進一步聚合:GROUP BY、TOP-N、窗口統計
  • 進一步減少 OLAP 計算負擔:讓流處理承擔更多計算工作
  • 多層數據架構:Kafka Bronze (原始數據) → :Kafka Silver (大寬表) → :Kafka Gold (聚合結果)

從基礎 JOIN 到進階運算,讓我們看看 Flink 如何支撐進一步的大規模數據處理!


上一篇
【知其然,更知其所以然】Day 21: Flink 核心概念全解析
下一篇
【知其然,更知其所以然】Day 23: 多層架構設計
系列文
「知其然,更知其所以然:什麼是 Real-time (Streaming) Pipeline?從造輪子到 Flink 與 RisingWave」26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言