廣告點擊系統(Ad Click Aggregator)最初的設計是以 DynamoDB 作為核心儲存層。架構簡潔,開發快速:API Gateway 收到點擊事件後,Lambda 把收到的 request 寫入 DynamoDB,查詢時再由另一支 Lambda 從 DynamoDB 讀出。
這個設計在流量低的時候表現完美。但當查詢頻率提升後,問題開始浮現,不止像上一篇文章說的, DynamoDB 的費用可能比較昂貴外,DynamoDB 的查詢彈性明顯不足以支撐日益複雜的統計需求。
上一篇文章已經介紹如何把原本的資料遷移到 PostgreSQL ,這篇文章要來說說 API 的部分,把 Data Source 從 DynamoDB 換成 Aurora PostgreSQL。

DynamoDB 的 table schema 設計如下:
Partition Key: ad_id (String)
Sort Key: click_id (String)
Impression Id: impression_id (String)
Ingestion Time: processedAt (String)
Source Url: source_url (String)
Ingestion Timestamp: timestamp (Number)
Click User Id: user_id (String)
這個設計對單筆寫入沒問題,但當下游服務需要:
ad_id 過去 30 天的所有點擊就必須把整個 partition 的資料都撈出來、在 Lambda 內做 in-memory 計算。資料量一大,就會撞上讀取費用和 scan 效率的雙重問題。
因為 DynamoDB 對查詢模式有嚴格限制 — 只能根據 Primary Key 或 Secondary Index 查詢。一旦有聚合或跨欄位篩選的需求,要麼預先設計好所有 access pattern,要麼把整個 partition 撈出來在 application-side 計算。
PostgreSQL 支援完整的 SQL:GROUP BY 、 COUNT(DISTINCT …) 、 WHERE ts BETWEEN … ,這些語法在 DynamoDB 上都需要自行用程式處理。