本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
此使用案例說明如何將 DynamoDB 做為線上商店 (或電子商店) 的資料存放區。
使用案例
使用者可在線上商店瀏覽各種產品,並進行購買。結帳時客戶可以使用折扣碼或禮品卡付款,並用信用卡支付剩餘金額。從數個倉庫中找出購買產品後,便會運送到客戶提供的地址。線上商店存放區的典型存取模式包括:
-
取得指定 的客戶 customerId
-
取得指定 的產品 productId
-
取得指定 的倉儲 warehouseId
-
透過 取得所有倉儲的產品庫存 productId
-
取得指定 的訂單 orderId
-
取得指定 的所有產品 orderId
-
取得指定 的發票 orderId
-
取得指定 的所有寄件 orderId
-
取得指定日期範圍 productId 中指定 的所有訂單
-
取得指定 的發票 invoiceId
-
取得指定 的所有付款 invoiceId
-
取得指定 的寄件詳細資訊 shipmentId
-
取得指定 的所有 寄件 warehouseId
-
取得指定 的所有產品的庫存 warehouseId
-
取得指定日期範圍 customerId 中指定 的所有發票
-
取得指定日期範圍內由 customerId 指定 訂購的所有產品
實體關係圖
這是我們將用來將 DynamoDB 建模為線上商店資料存放區的實體關係圖 (ERD)。

存取模式
針對如何使用 DynamoDB 做為線上商店的資料存放區,這些是可採用的存取模式。
-
getCustomerByCustomerId
-
getProductByProductId
-
getWarehouseByWarehouseId
-
getProductInventoryByProductId
-
getOrderDetailsByOrderId
-
getProductByOrderId
-
getInvoiceByOrderId
-
getShipmentByOrderId
-
getOrderByProductIdForDateRange
-
getInvoiceByInvoiceId
-
getPaymentByInvoiceId
-
getShipmentDetailsByShipmentId
-
getShipmentByWarehouseId
-
getProductInventoryByWarehouseId
-
getInvoiceByCustomerIdForDateRange
-
getProductsByCustomerIdForDateRange
架構設計演進
使用 沒有SQL適用於 DynamoDB 的 Workbench 匯入 AnOnlineShop_1.jsonAnOnlineShop
和名為 的新資料表。 OnlineShop
請注意,我們將分區索引鍵和排序索引鍵命名為通用名稱 PK
和 SK
,藉此可在同一個資料表中儲存不同類型的實體。
步驟 1:位址存取模式 1 (getCustomerByCustomerId
)
匯入 AnOnlineShop_2.json getCustomerByCustomerId
)。某些實體與其他實體並無關聯,因此我們將針對這些實體使用相同的 PK
和 SK
值。在範例資料中,請注意索引鍵字首為 c#
,以和稍後會從其他實體新增的 customerId
進行區別。也請於其他實體重複執行此做法。
若要處理此存取模式,可以利用 PK=customerId
和 SK=customerId
執行 GetItem
操作。
步驟 2:位址存取模式 2 (getProductByProductId
)
匯入 AnOnlineShop_3.json product
實體的存取模式 2 (getProductByProductId
)。產品實體字首為 p#
,並且已使用相同的排序索引鍵屬性來儲存 customerID
與 productID
。透過通用命名和垂直分割建立項目集合,可設計有效的單一資料表。
若要處理此存取模式,可以利用 PK=productId
和 SK=productId
執行 GetItem
操作。
步驟 3:位址存取模式 3 (getWarehouseByWarehouseId
)
匯入 AnOnlineShop_4.json warehouse
實體的存取模式 3 (getWarehouseByWarehouseId
)。目前我們已將 customer
、product
與 warehouse
實體加入同一個資料表,且這些實體均使用字首和 EntityType
屬性。類型屬性 (或字首命名) 能提升模型的可讀性。如果我們只將不同實體IDs的英數字元存放在相同的屬性中,則會影響可讀性。若少了識別符,就會難以分辨不同實體。
若要處理此存取模式,可以利用 PK=warehouseId
和 SK=warehouseId
執行 GetItem
操作。
Base 資料表:

步驟 4:位址存取模式 4 (getProductInventoryByProductId
)
匯入 AnOnlineShop_5.json getProductInventoryByProductId
)。 warehouseItem
實體用於追蹤每個倉儲中的產品數量。當倉庫新增或移除產品時,通常會更新此項目。如 所示ERD, many-to-manyproduct
和 之間存在關係warehouse
。在這裡,從 one-to-manyproduct
到 warehouse
的關係會建模為 warehouseItem
。之後,從 warehouse
到 one-to-many的關係也會product
建立模型。
可透過查詢 PK=ProductId
和 SK begins_with “w#“
處理存取模式 4。
關於 begins_with()
和其他可套用至排序索引鍵的表達式,詳細資訊請參閱索引鍵條件表達式。
Base 資料表:

步驟 5:位址存取模式 5 (getOrderDetailsByOrderId
) 和 6 (getProductByOrderId
)
匯入 AnOnlineShop_6.jsoncustomer
,將更多 product
、 和 warehouse
項目新增至資料表。然後,匯入 AnOnlineShop_7.jsonorder
,以解決存取模式 5 (getOrderDetailsByOrderId
) 和 6 () getProductByOrderId
的問題。您可以看到 one-to-manyorder
與 product
之間的關係,模型化為 orderItem 實體。
若想處理存取模式 5 (getOrderDetailsByOrderId
),請透過 PK=orderId
查詢資料表,了解與訂單相關的所有資訊,包括 customerId
和已訂購產品。
Base 資料表:

若想處理存取模式 6 (getProductByOrderId
),僅能以 order
讀取產品,此方法可透過利用 PK=orderId
和 SK begins_with “p#”
查詢資料表完成。
Base 資料表:

步驟 6:位址存取模式 7 (getInvoiceByOrderId
)
匯入 AnOnlineShop_8.jsoninvoice
實體新增至訂單項目集合,以處理存取模式 7 (getInvoiceByOrderId
)。若要處理此存取模式,可以利用 PK=orderId
和 SK begins_with
“i#”
執行查詢操作。
Base 資料表:

步驟 7:位址存取模式 8 (getShipmentByOrderId
)
匯入 AnOnlineShop_9.jsonshipment
實體新增至訂單項目集合,以解決存取模式 8 (getShipmentByOrderId
)。我們可透過在單一資料表設計中新增更多實體類型,擴展同一個的垂直分割模型。請注意,訂單項目集合中項目間的關係,並不同於 order
、shipment
、orderItem
及 invoice
實體間所擁有的關係。
若想透過 orderId
取得運送貨物,您可以利用 PK=orderId
和 SK begins_with “sh#”
執行查詢操作。
Base 資料表:

步驟 8:位址存取模式 9 (getOrderByProductIdForDateRange
)
在上個步驟中,我們建立了訂單項目集合。此存取模式具有新的查詢維度 (ProductID
和Date
),會要求您掃描整個資料表並篩選相關記錄,以擷取目標項目。為了解決此存取模式的問題,我們需要建立全域次要索引 (GSI)。匯入 AnOnlineShop_10.jsonorderItem
資料。目前資料內有 GSI1-PK
和 GSI1-SK
,分別為 GSI1
的分割區索引鍵和排序索引鍵。
DynamoDB 會自動將包含 GSI金鑰屬性的項目從資料表填入 。 GSI您不需要手動在 中進行任何額外的插入GSI。
若想處理存取模式 9,請利用 GSI1-PK=productId
和 GSI1SK between (date1,
date2)
查詢 GSI1
。
Base 資料表:

GSI1:

步驟 9:位址存取模式 10 (getInvoiceByInvoiceId
) 和 11 (getPaymentByInvoiceId
)
匯入 AnOnlineShop_11.jsongetInvoiceByInvoiceId
) 和 11 (getPaymentByInvoiceId
),兩者都與 相關invoice
。即使這兩種存取模式並不相同,仍須透過索引鍵條件以實現。Payments
的定義為 invoice
實體上具地圖資料類型的屬性。
注意
GSI1-PK
和 GSI1-SK
會超載以存放不同實體的相關資訊,以便可以從相同的 提供多個存取模式GSI。如需GSI超載的詳細資訊,請參閱 在 DynamoDB 中超載全域次要索引。
若想處理存取模式 10 和 11,請利用 GSI1-PK=invoiceId
和 GSI1-SK=invoiceId
查詢 GSI1
。
GSI1:

步驟 10:位址存取模式 12 (getShipmentDetailsByShipmentId
) 和 13 (getShipmentByWarehouseId
)
匯入 AnOnlineShop_12.jsongetShipmentDetailsByShipmentId
) 和 13 (getShipmentByWarehouseId
)。
請注意,shipmentItem
實體已新增至基底資料表上的訂單項目集合,以在單一查詢作業中擷取訂單的所有詳細資訊。
Base 資料表:

GSI1
分割區和排序索引鍵已用於建立 shipment
與 one-to-many之間的關係模型shipmentItem
。若想處理存取模式 12 (getShipmentDetailsByShipmentId
),請利用 GSI1-PK=shipmentId
和 GSI1-SK=shipmentId
查詢 GSI1
。
GSI1:

我們需要建立另一個 GSI(GSI2
),以建立 warehouse
和 之間的新 one-to-many關係模型shipment
,用於存取模式 13 (getShipmentByWarehouseId
)。若想處理此存取模式,請利用 GSI2-PK=warehouseId
和 GSI2-SK
begins_with “sh#”
查詢 GSI2
。
GSI2:

步驟 11:位址存取模式 14 (getProductInventoryByWarehouseId
)、15 (getInvoiceByCustomerIdForDateRange
) 和 16 (getProductsByCustomerIdForDateRange
)
匯入 AnOnlineShop_13.json getProductInventoryByWarehouseId
),請利用 GSI2-PK=warehouseId
和 GSI2-SK
begins_with “p#”
查詢 GSI2
。
GSI2:

若想處理存取模式 15 (getInvoiceByCustomerIdForDateRange
),請利用 GSI2-PK=customerId
和 GSI2-SK between
(i#date1, i#date2)
查詢 GSI2
。
GSI2:

若想處理存取模式 16 (getProductsByCustomerIdForDateRange
),請利用 GSI2-PK=customerId
和 GSI2-SK between
(p#date1, p#date2)
查詢 GSI2
。
GSI2:

注意
在無SQL工作台中,構面代表應用程式 DynamoDB 的不同資料存取模式。面向為您提供了一種查看資料表中的資料子集的方法,而無需查看不符合面向限制的記錄。面向是一種視覺資料建模工具,在 DynamoDB 中不作為可用的建構存在,因為其純粹用於輔助存取模式建模。
匯入 AnOnlineShop_facets.json
下表摘要整理了所有存取模式,以及結構描述設計處理這些模式的方式:
存取模式 | 基礎 table/GSI/LSI | 作業 | 分割區索引鍵值 | 排序索引鍵值 |
---|---|---|---|---|
getCustomerByCustomerId | 基本資料表 | GetItem | PK=customerId | SK=customerId |
getProductByProductId | 基本資料表 | GetItem | PK=productId | SK=productId |
getWarehouseByWarehouseId | 基本資料表 | GetItem | PK=warehouseId | SK=warehouseId |
getProductInventoryByProductId | BASE 資料表 | Query | PK=productId | SK begins_with "w#" |
getOrderDetailsByOrderId | BASE 資料表 | Query | PK=orderId | |
getProductByOrderId | BASE 資料表 | Query | PK=orderId | SK begins_with "p#" |
getInvoiceByOrderId | BASE 資料表 | Query | PK=orderId | SK begins_with "i#" |
getShipmentByOrderId | BASE 資料表 | Query | PK=orderId | SK begins_with "sh#" |
getOrderByProductIdForDateRange | GSI1 | Query | PK=productId | SK between date1 and date2 |
getInvoiceByInvoiceId | GSI1 | Query | PK=invoiceId | SK=invoiceId |
getPaymentByInvoiceId | GSI1 | Query | PK=invoiceId | SK=invoiceId |
getShipmentDetailsByShipmentId | GSI1 | Query | PK=shipmentId | SK=shipmentId |
getShipmentByWarehouseId | GSI2 | Query | PK=warehouseId | SK begins_with "sh#" |
getProductInventoryByWarehouseId | GSI2 | Query | PK=warehouseId | SK begins_with "p#" |
getInvoiceByCustomerIdForDateRange | GSI2 | Query | PK=customerId | SK between i#date1 and i#date2 |
getProductsByCustomerIdForDateRange | GSI2 | Query | PK=customerId | SK between p#date1 and p#date2 |
線上商店最終結構描述
以下是最終結構描述設計。若要將此結構描述設計下載為 JSON 檔案,請參閱 上的 DynamoDB 設計模式
基底資料表

GSI1

GSI2

使用此結構描述設計搭配 NoSQL Workbench
您可以將此最終結構描述匯入 NoSQL Workbench,這是一種視覺化工具,可為 DynamoDB 提供資料建模、資料視覺化和查詢開發功能,以進一步探索和編輯您的新專案。請依照下列步驟以開始使用:
-
下載無SQL Workbench。如需詳細資訊,請參閱下載無SQL適用於 DynamoDB 的 Workbench。
-
下載上列結構描述檔案,該檔案已採用 NoSQL Workbench JSON 模型格式。
-
將JSON結構描述檔案匯入 NoSQL Workbench。如需詳細資訊,請參閱匯入現有的資料模型。
-
匯入 NOSQL Workbench 後,您可以編輯資料模型。如需詳細資訊,請參閱編輯現有的資料模型。
-
若要視覺化您的資料模型、新增範例資料,或從CSV檔案匯入範例資料,請使用無SQL工作台的 Data Visualizer 功能。