iT邦幫忙

2026 iThome 鐵人賽

DAY 20
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 20 篇

Day 20|資料庫該選 RDS、Aurora,還是 DynamoDB?

  • 分享至 

  • xImage
  •  

上一篇比較了 S3、EBS 與 EFS,從應用程式的存取方式決定檔案放在哪裡。

但訂單、會員與庫存資料,除了保存之外,還需要查詢、更新,以及確保多筆資料能一起完成變更,這時就要進一步選擇資料庫。

AWS 常見的選項包括 Amazon RDS、Amazon Aurora 與 Amazon DynamoDB,選擇之前可以先確認:

資料之間有哪些關係?應用程式會怎麼查詢?哪些更新必須一起成功或失敗?

「資料很多」或「流量很大」還不足以決定服務選型,當相同的資料量,如果查詢方式不同,適合的資料庫也會不同。


先分清楚 RDS、Aurora 與 DynamoDB 的關係

Amazon RDS 是受管的關聯式資料庫服務,支援 PostgreSQL、MySQL、MariaDB、Oracle、SQL Server 與 Db2 等引擎。

Amazon Aurora 也是關聯式資料庫,而且屬於 RDS 服務的一部分,提供 MySQL 與 PostgreSQL 相容的引擎,選型時常見的比較是「RDS for PostgreSQL」與「Aurora PostgreSQL」,而非兩個完全無關的服務。

Amazon DynamoDB 則是全受管的 Serverless NoSQL 資料庫,主要使用 Key-value(鍵值)與 Document(文件)模型,應用程式通常透過 API 或 SDK,依照主鍵與索引存取資料。

比較項目 RDS 的一般關聯式引擎 Aurora MySQL/PostgreSQL DynamoDB
資料模型 關聯式 關聯式 鍵值/文件
主要存取方式 SQL SQL API、依鍵值與索引查詢
跨資料表 JOIN 支援 支援 不提供傳統關聯式 JOIN
交易 支援 支援 支援 ACID 交易
設計重點 資料關係、索引與查詢 關聯式設計,加上叢集與讀寫配置 存取模式、鍵值分布與索引

這篇提到的 Aurora,以 Aurora MySQL/PostgreSQL 為範圍。


RDS:需要關聯式模型與彈性查詢時的基本選擇

假設購物網站有兩張資料表。

Customers

customer_id name
1001 Harper
1002 Alex

Orders

order_id customer_id amount
5001 1001 1200
5002 1001 800
5003 1002 650

兩張表透過 customer_id 建立關聯,要查訂單屬於哪位會員可以使用:

SELECT
    c.name,
    o.order_id,
    o.amount
FROM customers AS c
JOIN orders AS o
    ON o.customer_id = c.customer_id;

如果後續要加入商品明細、付款狀態或配送資訊,也可以透過資料表關係與 SQL 組合查詢。

這種彈性適合客服後台、訂單管理等需求:今天依會員查訂單,明天依付款狀態與日期篩選,下個月又增加商品分類統計。

如果既有系統已使用 PostgreSQL 或 MySQL,搬到 AWS 時可優先評估對應的 RDS 引擎,這樣可以保留大部分既有資料模型與工具,再確認版本、擴充套件及功能相容性。

RDS 會協助處理基礎設施、備份與部分維護工作,但團隊仍然需要設計資料表、索引與查詢,使用受管資料庫,不會自動讓低效率的 SQL 變快。

高可用性與讀取擴展也要分別規劃,例如 Day 17 提到的 RDS Multi-AZ DB Instance,其 Standby 主要用於容錯移轉;如果目的是分擔讀取,則要評估 Read Replica 或其他適合的部署方式,不能把備援與讀取擴展當成同一件事。


Aurora:需要關聯式模型,但有更高的擴展與可用性需求

Aurora 同樣屬於關聯式資料庫,因此 SQL、資料表、JOIN 與交易等使用方式和前面的 RDS 類似。

差別主要在底層架構,典型的 Aurora 叢集包含:

  • Writer Instance:處理讀寫。
  • Reader Instance/Aurora Replica:處理唯讀流量,也可作為容錯移轉候選。
  • Cluster Volume:Writer 與 Reader 共用的叢集儲存層。
                   應用程式
                      │
           ┌──────────┴─────────┐
           │                    │
        讀寫連線              唯讀連線
           │                    │
           ▼                    ▼
     Writer Endpoint      Reader Endpoint
           │                    │
           ▼                    ▼
        Writer               Reader
           │                    │
           └──────────┬─────────┘
                      │
                      ▼
             共用 Cluster Volume
          (資料副本跨三個 AZ 儲存)

應用程式可以透過 Writer Endpoint 連到目前的 Writer,並透過 Reader Endpoint 將新的唯讀連線分配給 Aurora Replicas,不過應用程式仍然需要區分讀寫連線,建立 Reader 並不代表所有查詢都會自動完成讀寫分流。

因此,如果系統本身就適合關聯式資料庫,但進一步出現以下需求,就可以評估 Aurora:

  • 讀取量較大,需要多個 Reader 分擔查詢。
  • 負載波動明顯,希望透過 Aurora Serverless 調整運算容量。
  • 希望利用 Aurora Replica 提升高可用性與故障切換能力。
  • 有跨 Region 資料庫需求,需要評估 Aurora Global Database。

例如原本使用 PostgreSQL 的訂單系統,需要保留 JOIN、交易與複雜查詢,但讀取流量逐漸增加,就可以比較一般 RDS 搭配 Read Replica,和 Aurora 搭配多個 Reader 的成本與架構差異。

Aurora Serverless 可以依負載調整容量,但仍需要設定適合的容量範圍,並實際驗證尖峰時的擴展行為,它同樣不會自動解決低效率 SQL、交易鎖定或不合理的資料模型。

因此,Aurora 並不是因為「比 RDS 更進階」就一定更適合,而是當系統仍需要關聯式資料庫,同時又對讀取擴展、可用性、彈性容量或跨 Region 架構有進一步需求時,再評估它帶來的價值是否值得額外成本。


DynamoDB:先列出查詢,再設計 Key

DynamoDB 更強調 Access Pattern(存取模式):在建立資料表之前,先確認應用程式會怎麼查資料,再根據這些查詢設計主鍵與索引。

例如一個會員訂單功能需要:

  1. 查某位會員最近的訂單。
  2. 查某位會員在指定日期範圍內的訂單。
  3. 取得並更新已知完整主鍵的訂單。

可以先使用以下簡化設計:

Partition Key(分割區鍵) Sort Key(排序鍵) status amount
USER#1001 ORDER#20261003#4998 paid 800
USER#1001 ORDER#20261004#5001 pending 1200
USER#1002 ORDER#20261004#5002 paid 650

這種設計很適合「已知會員,再查他的訂單」:以會員作為 Partition Key,再利用 Sort Key 中的日期查詢指定範圍。

但如果需求變成:只知道 order_id = 5001,直接查出這筆訂單。

原本的主鍵就無法直接支援,因為查詢時不知道會員編號,若這也是固定需求,就需要另外建立 Global Secondary Index(GSI,全域次要索引) 作為新的查詢入口。

如果之後又出現:查所有會員中尚未付款,而且金額超過某個門檻的訂單。

同樣需要重新評估索引或資料模型,若大量需求最後都只能透過 Scan 掃描整張表再過濾,通常代表目前的 DynamoDB 模型與實際存取方式並不吻合,這也是 DynamoDB 和關聯式資料庫在選型上的重要差異。

如果系統的查詢方式固定,例如:

  • Session:依 Session ID 取得登入狀態。
  • 購物車:依會員編號取得購物車內容。
  • 工作狀態:依 request_id 取得處理進度。

這類「已知 Key → 取得資料」的存取模式通常很適合 DynamoDB。

反過來,如果需求經常出現新的篩選條件、多欄位查詢、關聯查詢,甚至需要臨時組合查詢,使用 RDS 或 Aurora 這類關聯式資料庫通常會比較直覺。

因此選 DynamoDB 時,不應只看資料是不是 JSON、是不是購物車或 Session,而要先問:系統會用哪些條件查資料,而且這些查詢模式是否足夠明確、穩定。

另外也要確認 Partition Key 能適度分散流量,避免大量請求長期集中在少數熱門 Key。


需要交易,不代表只能選關聯式資料庫

訂單系統可能要求:建立訂單、扣除庫存與使用優惠券,必須一起成功;其中一項失敗,就不能留下不完整的結果。

RDS/Aurora 可以透過資料庫交易,搭配條件更新或鎖定機制完成這類操作。

DynamoDB 也支援 ACID 交易 ,透過 TransactWriteItems,可以把多個項目的新增、更新、刪除與條件檢查組成一次全部成功或全部失敗的操作。

所以「需要交易」本身不足以淘汰 DynamoDB,還需要確認:

需求 選型上的影響
多筆已知資料必須一起更新 兩類資料庫都有交易能力
需要外鍵與關聯式約束 關聯式資料庫可以直接表達
經常跨表 JOIN、增加不同查詢條件 優先評估關聯式資料庫
依已知鍵值更新,並檢查目前狀態 DynamoDB 的條件寫入與交易也適合

放回實際需求該怎麼選?

以下用一個假設情境做決定。

一家公司的訂單系統已使用 PostgreSQL,客服與營運持續新增跨表查詢需求,這次要搬到 AWS,團隊熟悉 SQL,也沒有安排重寫資料存取層。

那可以優先評估 RDS for PostgreSQL,並依可用性目標評估 Multi-AZ 配置。

候選方案 這次的判斷 需要承擔的管理責任
RDS for PostgreSQL 優先選擇,保留既有模型與工具 容量規劃、索引、SQL 調校與復原驗證
Aurora PostgreSQL 保留比較,確認是否需要其叢集能力 相容性測試、讀寫配置、容量與成本評估
DynamoDB 本次先排除,改寫範圍超出遷移需求 重新設計鍵值、索引與應用程式資料存取方式

DynamoDB 在這次被排除,是因為改用它需要重新建模,而查詢需求仍然持續變動;Aurora 則需要用讀取擴展、容量調整或跨 Region 需求,證明採用它的收益。

在「既有 PostgreSQL 系統、查詢需求持續變動,而且本次不重寫資料存取層」的限制下,我會優先選擇 RDS for PostgreSQL,保留原有資料模型與工具;同時也需接受容量規劃、索引與 SQL 調校的責任。

同一套系統也可以把訂單放在關聯式資料庫,把適合鍵值存取的功能交給 DynamoDB,但每增加一種資料庫,就會增加監控、備份、權限與資料同步的責任,只有當某項功能有明確收益時,才會評估引入第二種資料庫。


下一篇

儲存與資料庫決定了資料如何保存與存取,接下來要選擇執行應用程式的地方。

下一篇會比較 EC2、容器與 Lambda,從執行時間、流量型態、環境控制需求與維運能力,判斷哪一種運算方式適合目前的工作負載。

參考資料


上一篇
Day 19|檔案該放 S3、EBS 還是 EFS?
下一篇
Day 21|應用程式該放 EC2、容器還是 Lambda?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言