

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 DynamoDB 中製作關聯式資料模型的最佳實務
<a name="bp-relational-modeling"></a>

本節提供在 Amazon DynamoDB 中建構關聯式資料模型的最佳實務。首先，我們要介紹傳統的資料模型建構概念。接著會說明使用 DynamoDB 相較於傳統關聯式資料庫管理系統的優點，讓您了解它如何消除 JOIN 操作的需求並減少額外負荷。

然後我們將說明如何設計可有效擴展的 DynamoDB 資料表。最後我們會提供一個範例來說明，如何在 DynamoDB 中建模關聯式資料的模型。

**Topics**
+ [傳統關聯式資料庫模型](#SQLtoNoSQL.relational-modeling2)
+ [DynamoDB 如何免除 JOIN 操作的需求](#bp-relational-modeling-joins)
+ [DynamoDB 交易如何消除寫入程序的負荷](#bp-relational-modeling-transactions)
+ [在 DynamoDB 中製作關聯式資料模型的第一步](bp-modeling-nosql.md)
+ [在 DynamoDB 中打造關聯式資料模型的範例](bp-modeling-nosql-B.md)

## 傳統關聯式資料庫模型
<a name="SQLtoNoSQL.relational-modeling2"></a>

傳統關聯式資料庫管理系統 (RDBMS) 會將資料儲存在標準化的關聯式結構中。關聯式資料模型的目標是減少資料的重複 (透過標準化)，以支援參考完整性並減少資料異常。

下列結構描述是一般訂單輸入應用程式的關聯式資料模型範例。此應用程式支援人力資源結構描述，並用它來為虛擬製造商的營運和業務支援系統提供支援。

![範例 RDBMS 結構描述。](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/RDBMS.png)


由於 DynamoDB 是非關聯式資料庫服務，相較於傳統關聯式資料庫管理系統，它提供了更多優勢。

## DynamoDB 如何免除 JOIN 操作的需求
<a name="bp-relational-modeling-joins"></a>

RDBMS 使用結構式查詢語言 (SQL) 將資料傳回至應用程式。由於資料模型的標準化，此類查詢通常需要使用 `JOIN` 運算子來合併來自一或多個資料表的資料。

例如，若要在可以運送任何項目的所有倉庫中，依庫存中的數量來排序產生購買順序項目清單，您可以對上述結構描述發出以下 SQL 查詢。

```
SELECT * FROM Orders
  INNER JOIN Order_Items ON Orders.Order_ID = Order_Items.Order_ID
  INNER JOIN Products ON Products.Product_ID = Order_Items.Product_ID
  INNER JOIN Inventories ON Products.Product_ID = Inventories.Product_ID
  ORDER BY Quantity_on_Hand DESC
```

此類 SQL 查詢提供存取資料的彈性 API，但他們需要的處理量很大。查詢中的每個聯結都會增加查詢的執行時期複雜度，因為每個資料表的資料必須暫存，然後再組裝以傳回結果集。

可能影響執行查詢時間長短的其他因素包括資料表的大小，以及要聯結的欄是否有索引。上述查詢會在數個資料表中起始複雜查詢，接著排序結果集。

免除使用 `JOINs` 的需求，是 NoSQL 資料建模的核心。這就是為什麼我們建置 DynamoDB 來支援 Amazon.com，以及為什麼 DynamoDB 可以在任何規模提供一致的效能。考慮到 SQL 查詢和 的執行時間複雜性`JOINs`，RDBMS 效能不會大規模保持不變。這會隨著客戶應用程式的增長而導致效能問題。

雖然資料標準化確實可減少儲存到磁碟的資料量，但通常影響效能的最受限資源是 CPU 時間和網路延遲。

DynamoDB 的建置目的是消除 `JOINs` (並鼓勵取消資料標準化) 和最佳化資料庫架構，以便透過對項目的單一請求來完全回應應用程式查詢，將這兩種限制降到最低。這些品質讓 DynamoDB 能夠在任何規模下提供個位數的毫秒速度效能。這是因為 DynamoDB 操作的執行時期複雜性對於常見存取模式來說是固定的，不會隨著資料大小而改變。

## DynamoDB 交易如何消除寫入程序的負荷
<a name="bp-relational-modeling-transactions"></a>

可能降低 RDBMS 速度的另一個因素，是使用交易來寫入標準化結構描述。如範例所示，大部分線上交易處理 (OLTP) 應用程式使用的關聯式資料結構儲存在 RDBMS 中時，必須細分並分散在多個邏輯資料表。

因此，符合 ACID 交易架構是必須的，以避免在應用程式嘗試讀取正處於寫入過程之物件時可能發生的競爭條件和資料完整性問題。此類交易框架與關聯式結構描述結合使用時，會大幅增加寫入程序的負荷。

在 DynamoDB 中實作交易會禁止 RDBMS 上常見的擴展問題發生。DynamoDB 以單一 API 呼叫的形式發出交易，並限制該單一交易中可存取的項目數量，藉此達到這個目的。長時間執行的交易可能因為交易永不關閉，所以長時間或永久鎖定資料，進而導致操作問題。

為了防止 DynamoDB 中發生此類問題，會使用兩個不同的 API 操作來實作交易：`TransactWriteItems` 和 `TransactGetItems`。這些 API 操作沒有 RDBMS 中常見的開始和結束語義。此外，DynamoDB 在交易中有 100 個項目的存取限制，同樣是為了防止交易長時間執行。若要進一步了解 DynamoDB 交易，請參閱[使用交易](transactions.md)。

基於這些原因，當您的企業需要對高流量查詢提供低延遲回應時，在技術與經濟的考量上通常會利用 NoSQL 系統。Amazon DynamoDB 可避免這些問題，協助解決限制關聯式系統可擴展性的問題。

基於以下原因，RDBMS 的效能通常無法適當地擴展：
+ 因此會使用昂貴的聯結來重新組合必要的查詢結果檢視。
+ 資料庫將資料標準化並存放在多個資料表中，這些資料表需要多個查詢來寫入至磁碟中。
+ 這通常會引發 ACID 合規交易系統的效能成本，

DynamoDB 順利擴展的原因為下：
+ 結構描述靈活性可讓 DynamoDB 在單一項目中存放複雜階層資料。
+ 複合索引鍵設計可讓您將相關的項目存放在相同資料表的鄰近位置。
+ 交易以單一操作形式執行。可存取的項目數限制為 100 個，以避免操作長時間執行。

對資料存放的查詢變得簡單多了，通常是使用以下格式：

```
SELECT * FROM Table_X WHERE Attribute_Y = "somevalue"
```

與先前範例中的 RDBMS 相比，DynamoDB 傳回要求資料的程序簡單許多。