本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
在 DynamoDB 中打造關聯式資料模型的範例
此範例說明如何在 Amazon DynamoDB 中打造關聯式資料模型。DynamoDB 資料表設計會與 關聯式模型 中顯示的關聯式排序項目結構描述相對應。其遵循 相鄰清單設計模式,此為在 DynamoDB 中呈現關聯式資料結構的常見方式。
該設計模式需要您定義一組實體類型,其通常會與關聯式結構描述中的各種資料表相關聯。系統接著會使用複合 (分割區索引鍵與排序索引鍵) 主要索引鍵來將實體項目新增至資料表。這些實體項目的分割區索引鍵為唯一辨識項目的屬性,且在所有項目上通常稱為 PK
。排序索引鍵屬性包含您可以用於已反轉索引或全域次要索引的屬性值。此通常稱為 SK
。
您定義的下列實體會支援關聯式排序項目結構描述。
-
HR-Employee:PK:EmployeeID、SK:員工名稱
-
HR-Region:PK:RegionID、SK:區域名稱
-
HR-國家 - PK: CountryId,SK:國家名稱
-
HR-Location:PK:LocationID、SK:國家/地區名稱
-
HR-Job:PK:JobID、SK:工作標題
-
HR-Department - PK:DepartmentIDSK: DepartmentName
-
OE-客戶 - PK:CustomerIDSK: AccountRepID
-
OE-Order:PK OrderID、SK:CustomerID
-
OE-Product:PK:ProductID、SK:產品名稱
-
OE-Warehouse:PK:WarehouseID、SK:區域名稱
將這些實體項目新增至資料表後,您可以將邊緣項目新增至實體項目分割區來定義其中的關係。下列資料表示範此步驟。

在此範例中,資料表上的 Employee
、Order
和 Product
Entity
分割區擁有其他邊緣項目,其中包含對資料表上其他實體項目的指標。接下來,定義幾個全域次要索引 (GSIs),以支援先前定義的所有存取模式。實體項目不會全都將相同類型的值用在主要索引鍵或排序索引鍵屬性。只需要擁有要插入資料表上的主要索引鍵與排序索引鍵屬性。
其中一些實體使用適當的名稱,而其他實體則使用其他實體IDs作為排序索引鍵值,允許相同的全域次要索引來支援多種類型的查詢。此技術稱為GSI過載 。其會有效地將 20 個全域次要索引的預設限制降到最低,以用於包含多個項目類型的資料表。這在下圖中顯示為 GSI 1。

GSI 2 旨在支援相當常見的應用程式存取模式,即取得資料表上具有特定狀態的所有項目。針對在可用狀態間含不平均項目發佈的大型資料表,此存取模式可能會造成經常性索引鍵值,除非項目發佈的範圍是在可平行查詢的多於一個邏輯分割區中。此設計模式稱為 write sharding
。
為了完成 2 GSI 的這項操作,應用程式會將 GSI 2 個主要金鑰屬性新增至每個訂單項目。其會填入 0-N 範圍中的某個亂數,其中 N 通常可以使用以下公式來計算,除非有特定不這麼做的原因。
ItemsPerRCU = 4KB / AvgItemSize PartitionMaxReadRate = 3K * ItemsPerRCU N = MaxRequiredIO / PartitionMaxReadRate
例如,假設您預期以下情況:
-
系統中將會有高達 200 萬的訂單,5 年內將成長至 300 萬。
-
這些訂單最多 20% 在任何指定時間都會處於 OPEN 狀態。
-
平均訂單記錄約為 100 個位元組,其中訂單分割區中有三個
OrderItem
記錄,每個記錄約為 50 個位元組,為您提供平均訂單實體大小為 250 個位元組。
針對該資料表,N 因素計算看起來會與以下類似。
ItemsPerRCU = 4KB / 250B = 16 PartitionMaxReadRate = 3K * 16 = 48K N = (0.2 * 3M) / 48K = 13
在此情況下,您需要在 2 上將所有訂單分佈到至少 13 GSI 個邏輯分割區,以確保所有OPEN
狀態Order
項目的讀取不會導致實體儲存層上的熱分割區。此為填充此數字以允許在資料集異常狀況的最佳實務。因此使用 N = 15
的模型可能適用於此。如前所述,您可以新增隨機 0–N 值至每個 的 GSI 2 個 PK 屬性OrderItem
,Order
並記錄插入資料表。
此明細假設需要搜尋所有 OPEN
發票的存取模式並不常發生,因此您可以使用高載容量來滿足要求。您可以使用 State
和 Date Range
排序索引鍵 (Sort Key) 條件來查詢下列全域次要索引,以依需要產生子集或為給定狀態的所有 Orders
。

在此範例中,項目會隨機在 15 邏輯分割區中發佈。此結構會在存取模式需要大量將擷取的項目時運作。因此,15 個執行緒的其中之一不可能會傳回可能代表浪費容量的空結果集。查詢一律使用 1 個讀取容量單位 (RCU) 或 1 個寫入容量單位 (WCU),即使沒有傳回任何內容或沒有寫入任何資料。
如果存取模式需要對此全域次要索引進行高速查詢 (其會傳回稀疏結果集),最好使用雜湊演算法來發佈項目 (不使用隨機模式)。在此案例中,執行時間執行查詢時,您可能會選取已知的屬性,並在插入項目時,將該屬性雜湊至 0-14 索引鍵空間。您可以有效率地透過全域次要索引來讀取它們。
最後,您可以再次瀏覽先前定義的存取模式。以下是您可以與應用程式 DynamoDB 版本一起使用以進行容納的存取模式清單與查詢條件。
S. 編號 | 存取模式 | 查詢條件 |
---|---|---|
1 |
按員工 ID 查詢員工詳細資訊 |
資料表的主要金鑰,ID="HR-EMPLOYEE" |
2 |
按員工姓名查詢員工詳細資訊 |
使用 GSI-1, PK="Employee Name" |
3 |
僅取得員工的目前工作詳細資訊 |
資料表上的主索引鍵,PK=HR-EMPLOYEE-1,SK 開頭為「JH」 |
4 |
取得某個日期範圍內的客戶訂單 |
使用 GSI-1、PK=CUSTOMER1、SK="STATUS-DATE",針對每個 StatusCode |
5 |
顯示所有客戶日期範圍OPEN狀態的所有訂單 |
使用 GSI-2,PK= 平行查詢範圍 【0.。N】,SK 介於 OPEN-Date1 和 OPEN-Date2 之間 |
6 |
最近僱用的所有員工 |
使用 GSI-1、PK="HR-CONFIDENTIAL'、SK > date1 |
7 |
尋找特定倉庫中的所有員工 |
使用 GSI-1,PK=WAREHOUSE1 |
8 |
取得產品的所有 Orderitems (訂單項目),包括倉庫位置庫存 |
使用 GSI-1,PK=PRODUCT1 |
9 |
按客戶代表取得客戶 |
使用 GSI-1,PK=ACCOUNT-REP |
10 |
按客戶代表和日期取得訂單 |
針對每個 使用 GSI-1、PK=ACCOUNT-REP、SK="STATUS-DATE" StatusCode |
11 |
取得特定職稱的所有員工 |
使用 GSI-1,PK=JOBTITLE |
12 |
按產品和倉庫取得庫存 |
資料表上的主索引鍵,PK=OE-PRODUCT1,SK=PRODUCT1 |
13 |
取得產品總庫存 |
資料表上的主索引鍵,PK=OE-PRODUCT1,SK=PRODUCT1 |
14 |
按訂單總計和銷售週期排名取得客戶代表 |
使用 GSI-1、PK=YYYY-Q1、 scanIndexForward=False |