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

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

GSI 2 設計為支援常見的應用程式存取模式,以在擁有特定狀態的資料表上取得所有項目。針對在可用狀態間含不平均項目發佈的大型資料表,此存取模式可能會造成經常性索引鍵值,除非項目發佈的範圍是在可平行查詢的多於一個邏輯分割區中。此設計模式稱為 write sharding
。
若要針對 GSI 2 達成此模式,應用程式會將 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
在此案例中,您需要將所有訂單發佈在 GSI 2 上至少 13 個邏輯分割區中,以確保含 OPEN
狀態的所有 Order
項目的讀取不會對實體儲存層造成經常性分割區。此為填充此數字以允許在資料集異常狀況的最佳實務。因此使用 N = 15
的模型可能適用於此。如先前所述,您透過將 0-N 值新增至每個 Order
與 OrderItem
記錄的 GSI 2 PK 屬性來執行。
此明細假設需要搜尋所有 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=「員工名稱」 |
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 |