

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

# 在 DynamoDB 中設計與有效運用分割區索引鍵的最佳實務
<a name="bp-partition-key-design"></a>

唯一識別 Amazon DynamoDB 資料表中每個項目的主索引鍵，可以是簡易 (僅分割區索引鍵) 或複合 (分割區索引鍵與排序索引鍵的組合)。

建議設計應用程式，使其在資料表內所有分割區索引鍵及其次要索引中均勻運作。您可以確定應用程式需要的存取模式，並估計每個資料表和次要索引所需的讀取和寫入單位。

**注意**  
動態調整容量適用於隨需模式與佈建容量。

每個 DynamoDB 資料表分割區設計為可提供每秒最多 3,000 個讀取單位與 1,000 個寫入單位。一個讀取容量單位代表每秒一次高度一致性讀取，或每秒兩次最終一致讀取，適用於大小上限 4 KB 的項目。一個寫入容量單位代表每秒一次寫入操作，適用於大小上限 1 KB 的項目。

評估資料表分割區輸送量限制時，必須考慮項目大小。例如，若資料表項目大小為 20 KB，單次一致性讀取操作將耗用 5 個讀取單位。這表示在達到分割區限制前，可同時對該項目每秒執行 600 次一致性讀取操作。所有分割區的總輸送量可能受佈建模式的設定輸送量或隨需模式下資料表層級限制所制約。如需詳細資訊，請參閱 [Service Quotas](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ServiceQuotas.html)。

**Topics**
+ [在 DynamoDB 中設計分割區索引鍵以有效分配工作負載](bp-partition-key-uniform-load.md)
+ [使用寫入碎片以在 DynamoDB 資料表中平均分配工作負載](bp-partition-key-sharding.md)
+ [在將資料上傳至 DynamoDB 時有效分配寫入活動](bp-partition-key-data-upload.md)

# 在 DynamoDB 中設計分割區索引鍵以有效分配工作負載
<a name="bp-partition-key-uniform-load"></a>

資料表主索引鍵的分割區索引鍵部分，決定了已儲存資料表資料的邏輯分割區。因此會影響底層的實體分割區。不能有效分配 I/O 請求的分割區索引鍵設計可能會造成「經常性」分割區，因此導致限流並且無法有效地使用已佈建的 I/O 容量。

資料表已佈建輸送量的最佳使用情況，不僅取決於各個項目的工作負載模式，還取決於分割區索引鍵設計。這並不表示您必須存取所有分割區索引鍵值才能達到有效率的輸送量層級，也不表示所存取之分割區索引鍵值的百分比必須很高。這表示您的工作負載存取的分割區索引鍵值越獨特，這些請求將越多地分佈在已分割區空間中。一般而言，隨著已存取分割區索引鍵值與總分割區索引鍵值的比例提升，您將更有效率地運用佈建輸送量。

以下是一些常用分割區索引鍵結構描述的已佈建輸送量效率比較。


****  

| 分割區索引鍵值 | 一致性 | 
| --- | --- | 
| 使用者 ID，其中應用程式有許多使用者。 | 好 | 
| 狀態碼，其中只有一些可能的狀態碼。 | 不好 | 
| 項目建立日期，捨入到最接近的時間週期 (例如日期、小時、分鐘)。 | 不好 | 
| 裝置 ID，其中每部裝置會依相當類似的間隔存取資料。 | 好 | 
| 裝置 ID，其中即使追蹤多個裝置，其中一部裝置也會明顯比其他所有裝置更熱門。 | 不好 | 

如果單一資料表只有少量的分割區索引鍵值，請考慮在更多相異分割區索引鍵值之間分佈您的寫入操作。換句話說，請結構化主索引鍵元素，以避免某個「經常性」(高度請求) 的分割區索引鍵值使整體效能變慢。

例如，請考慮使用具有複合主鍵的資料表。分割區索引鍵代表項目的建立日期，已捨入到最接近的日期。排序索引鍵是項目識別符。在指定的日期 (假設是 `2014-07-09`)，**所有**新項目都會寫入單一分割區索引鍵值 (和對應的實體分割區)。

如果資料表完全符合單一分割區 (考慮到資料會隨時間成長)，而且您應用程式的讀取與寫入輸送量需求不超過單一分割區的讀取與寫入能力，則您的應用程式應不會遇到由於分割所造成的非預期限流。

若要使用適用於 DynamoDB 的 NoSQL Workbench 來協助視覺化您的分割區索引鍵設計，請參閱 [使用 NoSQL Workbench 建立資料模型](workbench.Modeler.md)。

# 使用寫入碎片以在 DynamoDB 資料表中平均分配工作負載
<a name="bp-partition-key-sharding"></a>

在 Amazon DynamoDB 中的分割區索引鍵空間分配寫入的一個好方法是拓展空間。您可以數種不同的方式來執行此動作：您可以在分割區索引鍵值中新增隨機數字，以便在分割區之間分配項目。或者，您可以使用根據您查詢內容計算的數字。

## 使用隨機尾碼的碎片
<a name="bp-partition-key-sharding-random"></a>

要在分割區索引鍵空間中更平均地分佈負載的方法，即是在分割區索引鍵值的結尾新增一個亂數。如此您就能在較大的空間中將寫入隨機化。

例如，對於代表今天日期的分割區索引鍵，您可以選擇 `1` 到 `200` 間的一個亂數，並將其串連到日期做為尾碼。這會產生分割區索引鍵值，例如 `2014-07-09.1`、`2014-07-09.2`... 到 `2014-07-09.200`。因為您隨機化了分割區索引鍵，每天對資料表的寫入會平均分配在多個分割區中。這可帶來更優良的平行處理與更高的整體輸送量。

然而，若要讀取指定日期的所有項目，您需要查詢所有尾碼的項目，接著合併結果。例如，您會先對分割區索引鍵值 `2014-07-09.1` 發出 `Query` 請求。再對 `2014-07-09.2` 發出另一個 `Query`，依此類推直到 `2014-07-09.200`。最後，您的應用程式需要合併所有該等 `Query` 請求的結果。

## 使用計算尾碼的碎片
<a name="bp-partition-key-sharding-calculated"></a>

隨機化的策略可大幅改善寫入輸送量。由於您不知道寫入項目時所使用的尾碼值，因此很難讀取特定項目。若要讓讀取個別項目變得比較容易，您可以使用不同的策略。不使用亂數以在分割區中分佈項目，而是使用您可以計算的數字 (根據您想要查詢之項目)。

考量先前的範例，其中資料表會使用分割區索引鍵中的今天日期。現在假設每個項目有可存取的 `OrderId` 屬性，且您經常需要依訂單 ID (除了日期) 來尋找項目。在您的應用程式將項目寫入資料表之前，可根據訂單 ID 計算雜湊尾碼並將其附加至分割區索引鍵日期。計算應會產生介於 1 到 200 之間的數字，此分佈非常平均，與隨機策略產生的結果相當類似。

一個簡單的計算便足以說明，例如訂單 ID 中字元之 UTF-8 字碼指標值的乘積：模數 200，\$1 1。分割區索引鍵值會是與計算結果串聯的日期。

有了這項策略，即可在分割區索引鍵值之間，以及實體分割區之間平均分配寫入。您可以輕鬆地對特定項目與日期執行 `GetItem` 操作，因為您可以計算對特定 `OrderId` 值的分割區索引鍵值。

若要讀取指定日期的所有項目，您仍然需要 `Query` 每個 `2014-07-09.N` 索引鍵 (其中 `N` 是 1-200)，而且您的應用程式需要合併所有結果。好處是您能避免讓單一「經常性」分割區索引鍵值承受所有工作負載。

**注意**  
如需為了處理大量時間序列資料而設計的有效策略，請參閱 [時間序列資料](bp-time-series.md)。

# 在將資料上傳至 DynamoDB 時有效分配寫入活動
<a name="bp-partition-key-data-upload"></a>

通常，當您從其他資料來源載入資料時，Amazon DynamoDB 會將資料表資料分割在多個伺服器上。如果您同時將資料上傳到所有已配置的伺服器，就能獲得更好的效能。

例如，假設您想要將使用者訊息上傳至使用複合主鍵的 DynamoDB 資料表，該資料表將 `UserID` 作為分割區索引鍵並將 `MessageID` 作為排序索引鍵。

當您上傳資料時，您可以採取的一種方法是一個接一個地上傳每位使用者的所有訊息項目：


****  

| UserID | MessageID | 
| --- | --- | 
| U1 | 1 | 
| U1 | 2 | 
| U1 | ... | 
| U1 | …最多可達 100 | 
| U2 | 1 | 
| U2 | 2 | 
| U2 | ... | 
| U2 | …最多可達 200 | 

這個案例中的問題是您沒有將寫入請求分配到跨分割區索引鍵值的 DynamoDB。您一次需要一個分割區索引鍵值並上傳其所有項目，再轉到下一個分割區索引鍵值並執行相同操作。

在幕後，DynamoDB 會跨多個伺服器分割資料表中的資料。若要充分使用為資料表佈建的所有輸送容量，您必須將工作負載分配至各分割區索引鍵值。若您將不均勻數量的上傳工作導向所有具有相同分割區索引鍵值的項目，便無法完全使用 DynamoDB 為資料表佈建的所有資源。

您可以使用排序索引鍵，從每個分割區索引鍵值載入一個項目，再從每個分割區索引鍵值載入另一個項目，依此類推：


****  

| UserID | MessageID | 
| --- | --- | 
| U1 | 1 | 
| U2 | 1 | 
| U3 | 1 | 
| ... | ... | 
| U1 | 2 | 
| U2 | 2 | 
| U3 | 2 | 
| ... | ... | 

此序列中的每次上傳都會使用不同的分割區索引鍵值，讓更多 DynamoDB 伺服器同時處於忙碌狀態，並改善您的輸送量效能。