

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

# 在 DynamoDB 中管理全域次要索引
<a name="GSI.OnlineOps"></a>

本節說明如何在 Amazon DynamoDB 中建立、修改和刪除全域次要索引。

**Topics**
+ [建立具有全域次要索引的資料表](#GSI.Creating)
+ [描述資料表上的全域次要索引](#GSI.Describing)
+ [將全域次要索引新增至現有資料表](#GSI.OnlineOps.Creating)
+ [刪除全域次要索引](#GSI.OnlineOps.Deleting)
+ [建立期間修改全域次要索引](#GSI.OnlineOps.Creating.Modify)

## 建立具有全域次要索引的資料表
<a name="GSI.Creating"></a>

若要建立具有一或多個全域次要索引的資料表，請搭配 `CreateTable` 參數使用 `GlobalSecondaryIndexes` 操作。為達最大的查詢靈活性，您最多可以為每個資料表建立 20 個全域次要索引 (預設配額)。

您必須指定一個屬性做為分割區索引鍵。您可以選擇為排序索引鍵指定另一個屬性。上述任一索引鍵屬性皆不需與資料表的索引鍵屬性相同。例如，在 *GameScores* 表中 (請參閱 [在 DynamoDB 中使用全域次要索引](GSI.md))，`TopScore` 和 `TopScoreDateTime` 都不是索引鍵屬性。您可以建立分割區索引鍵為 `TopScore`、排序索引鍵為 `TopScoreDateTime` 的全域次要索引。您可能會使用這類索引來判斷高分與一天中玩遊戲的時間之間是否有相互關聯性。

每個索引鍵屬性都必須是類型為 `String`、`Number` 或 `Binary` 的純量。(而不可以是文件或集合)。您可以將任何資料類型的屬性投影到全域次要索引。這包括純量、文件和集合。如需資料類型的完整清單，請參閱 [資料類型](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)。

如果使用的是佈建模式，您必須為索引提供 `ProvisionedThroughput` 設定，包含 `ReadCapacityUnits` 和 `WriteCapacityUnits`。這些佈建輸送量設定與資料表的佈建輸送量設定無關，但運作方式類似。如需詳細資訊，請參閱 [全域次要索引的佈建輸送量考量](GSI.md#GSI.ThroughputConsiderations)。

 全域次要索引會從基礎資料表繼承讀取/寫入容量模式。如需詳細資訊，請參閱[切換 DynamoDB 容量模式時的注意事項](bp-switching-capacity-modes.md)。

**注意**  
 建立新 GSI 時，檢查您選擇的分割區索引鍵是否會在新索引的分割區索引鍵值之間產生資料或流量的不均勻分佈或小範圍分佈，這一點非常重要。如果發生這種情況，您可能會看到回填和寫入操作同時發生，並限流對基礎資料表的寫入。該服務會採取措施以將此情況的可能性降至最低，但沒有與索引分割區索引鍵、所選擇的投射或主索引鍵稀疏程度有關的客戶資料形狀的洞察。  
如果您懷疑新的全域次要索引在分割區索引鍵值上可能具有小範圍或偏斜的資料或流量分佈，請在將新索引新增到對操作而言重要的資料表之前，考慮以下項目。  
在應用程式驅動的流量為最少時新增索引可能是最安全的做法。
考慮在基礎資料表和索引上啟用 CloudWatch Contributor Insights。這將為您的流量分佈提供有價值的洞察。
 在整個過程中觀看 `ThrottledRequests`、 `WriteThrottleEvents`和 `OnlineIndexPercentageProgress` CloudWatch 指標。視需要調整佈建的寫入容量，以便在合理的時間內完成回填，而不會對進行中的操作造成任何重大限流影響。 `OnlineIndexConsumedWriteCapacity`和 `OnlineThrottleEvents` 預期在索引回填期間會顯示 0。
如果您因為寫入限流而發生操作影響，請準備好取消索引建立。

## 描述資料表上的全域次要索引
<a name="GSI.Describing"></a>

若要檢視資料表上所有全域次要索引的狀態，請使用 `DescribeTable` 操作。回應的 `GlobalSecondaryIndexes` 部分會顯示資料表上的所有索引，以及每個索引的目前狀態 (`IndexStatus`)。

全域次要索引的 `IndexStatus` 會是下列其中一項：
+ `CREATING`：正在建立索引，尚無法使用。
+ `ACTIVE`：索引已可供使用，應用程式可以在索引上執行 `Query` 操作。
+ `UPDATING`：正在變更索引的佈建輸送量設定。
+ `DELETING`：正在刪除索引，無法再使用。

當 DynamoDB 建置完全域次要索引時，索引狀態會從 `CREATING` 變更為 `ACTIVE`。

## 將全域次要索引新增至現有資料表
<a name="GSI.OnlineOps.Creating"></a>

若要將全域次要索引新增至現有資料表，請搭配 `GlobalSecondaryIndexUpdates` 參數使用 `UpdateTable` 操作。您必須提供下列項目：
+ 索引名稱。該名稱在資料表的所有索引中必須是唯一的。
+ 索引的索引鍵結構描述。您必須指定一個屬性做為索引的分割區索引鍵，並可以選擇性地指定另一個屬性做為索引的排序索引鍵。上述任一索引鍵屬性皆不需與資料表的索引鍵屬性相同。每個結構描述屬性的資料類型都必須是純量：`String`、`Number` 或 `Binary`。
+ 要從資料表投影到索引的屬性：
  + `KEYS_ONLY`：索引中的每個項目都只包含資料表分割索引鍵和排序索引鍵值，以及索引鍵值。
  + `INCLUDE`：除了 `KEYS_ONLY` 中描述的屬性外，次要索引會包含您指定的其他非索引鍵屬性。
  + `ALL`：索引包含來源資料表中的所有屬性。
+ 索引的佈建輸送量設定，包含 `ReadCapacityUnits` 和 `WriteCapacityUnits`。這些佈建輸送量設定與資料表的佈建輸送量設定無關。

每個 `UpdateTable` 操作只能建立一個全域次要索引。

### 索引建立階段
<a name="GSI.OnlineOps.Creating.Phases"></a>

當您將新的全域次要索引新增至現有資料表時，資料表在索引建置時仍可繼續使用。但新的索引在其狀態從 `CREATING` 變更為 `ACTIVE` 前，都不可進行 Query 操作。

**注意**  
全域次要索引建立不使用 Application Auto Scaling。提高 `MIN` Application Auto Scaling 容量不會減少全域次要索引的建立時間。

DynamoDB 幕後的索引建置分為兩個階段：

**資源配置**  
DynamoDB 會配置建立索引所需的運算和儲存資源。  
在資源配置階段，`IndexStatus` 屬性是 `CREATING`，而 `Backfilling` 屬性是 false。您可使用 `DescribeTable` 操作擷取資料表的狀態和其所有次要索引。  
當索引處於資源配置階段時，您無法刪除索引或刪除其父資料表。您也無法修改索引或資料表的佈建輸送量。您無法新增或刪除資料表上的其他索引。不過，您可以修改這些其他索引的佈建輸送量。

**回填**  
對於資料表中的每個項目，DynamoDB 會根據屬性的投影，判斷將哪一組屬性寫入索引 (`KEYS_ONLY`、`INCLUDE` 或 `ALL`)。然後它會將這些屬性寫入索引。在回填階段期間，DynamoDB 會追蹤正在資料表中新增、刪除或更新的項目。也會適當地在索引中新增、刪除或更新這些項目的屬性。  
在回填階段，`IndexStatus` 屬性會設為 `CREATING`，而 `Backfilling` 屬性是 true。您可使用 `DescribeTable` 操作擷取資料表的狀態和其所有次要索引。  
當索引正在回填時，您無法刪除其父資料表。但您仍然可以刪除索引，或修改資料表及其任何全域次要索引的佈建輸送量。  
在回填階段，違規項目的寫入可能一部分成功，而一部分則遭到拒絕。回填後，所有違反新索引鍵結構描述的項目寫入都會遭到拒絕。建議您在回填階段完成後執行 Violation Detector 工具，以偵測和解決任何可能已發生的索引鍵違規情況。如需詳細資訊，請參閱 [偵測和修正 DynamoDB 中的索引鍵違規情況](GSI.OnlineOps.ViolationDetection.md)。

進行資源配置和回填階段時，索引的狀態為 `CREATING`。在這期間，DynamoDB 會對資料表執行讀取操作。從基礎資料表填入全域次要索引的讀取操作不需支付費用。

當索引建置完成時，其狀態會變更為 `ACTIVE`。您無法 `Query` 或 `Scan` 索引，直到其 `ACTIVE` 為止。

**注意**  
在部分情況下，DynamoDB 會因索引鍵違規情況而無法將資料表中的資料寫入索引。如果發生下列情況，就會發生此情形：  
屬性值的資料類型與索引鍵結構描述資料類型的資料類型不相符。
屬性的大小超過索引鍵屬性的最大長度。
索引鍵屬性具有空字串或空的二進制屬性值。
索引鍵違規情況不會影響全域次要索引建立。不過，當索引變成 `ACTIVE` 時，索引中不會出現違規索引鍵。  
DynamoDB 提供獨立工具來尋找和解決這些問題。如需詳細資訊，請參閱 [偵測和修正 DynamoDB 中的索引鍵違規情況](GSI.OnlineOps.ViolationDetection.md)。

### 將全域次要索引新增至大型資料表
<a name="GSI.OnlineOps.Creating.LargeTable"></a>

建置全域次要索引所需的時間取決於幾個因素，例如：
+ 資料表的大小
+ 資料表中符合納入索引資格的項目數目
+ 投影到索引的屬性數目
+ 索引建置期間主要資料表上的寫入活動

如果您要將全域次要索引新增至極大的資料表，建立程序可能需要很久才能完成。若要監控進度並判斷索引是否有足夠的寫入容量，請參閱下列 Amazon CloudWatch 指標：
+ `OnlineIndexPercentageProgress`

如需與 DynamoDB 相關的 CloudWatch 指標的詳細資訊，請參閱 [DynamoDB 指標](metrics-dimensions.md#dynamodb-metrics)。

**重要**  
在建立或更新全域次要索引之前，您可能需要允許提列非常大的資料表。請聯絡 AWS Support 以允許列出您的資料表。

回填索引時，DynamoDB 會使用內部系統容量從資料表讀取。這是要將索引建立的影響降到最小，並確保資料表的讀取容量不會用盡。

## 刪除全域次要索引
<a name="GSI.OnlineOps.Deleting"></a>

如果您不再需要全域次要索引，可以使用 `UpdateTable` 操作將其刪除。

每個 `UpdateTable` 操作只能刪除一個全域次要索引。

刪除全域次要索引時，父資料表中所有讀取和寫入活動皆不受影響。當刪除正在進行時，仍可修改其他索引上的佈建輸送量。

**注意**  
當您使用 `DeleteTable` 動作刪除資料表時，也會刪除該資料表中所有全域次要索引。
您的帳戶將不會因全域次要索引的刪除操作而被收取費用。

## 建立期間修改全域次要索引
<a name="GSI.OnlineOps.Creating.Modify"></a>

當索引建置時，您可以使用 `DescribeTable` 操作來判斷它所處的階段。索引的描述包含布林值屬性 `Backfilling`，指出 DynamoDB 目前是否正在將資料表中的項目載入索引。如果 `Backfilling` 為 true，則資源配置階段已完成，且正在回填索引。

在回填階段，您可以刪除正在建立的索引。在這段階段，您無法新增或刪除資料表上的其他索引。

**注意**  
針對已在 `CreateTable` 操作中建立的索引，`Backfilling` 屬性不會出現在 `DescribeTable` 輸出中。如需詳細資訊，請參閱[索引建立階段](#GSI.OnlineOps.Creating.Phases)。