{DynamoDB}セカンダリインデックスを使用したデータアクセス性の向上

グローバルセカンダリインデックス
パーティションキーのみ or パーティションキーとソートキー
・サイズ制限なし
・既存のテーブルに追加、削除できる
・結果整合性
・ベーステーブルと異なるキャパシティーを使用
・テーブルごとに最大20個

ローカルセカンダリインデックス
パーティションキーとソートキー
パーティションキーの値毎に10GBまで
・既存のテーブルに追加、削除できない
・結果整合性 or 強い整合性
・ベーステーブルのキャパシティーを共用
・テーブルごとに最大5個


(1) グローバルセカンダリインデックス

-- 1. テストテーブル作成
aws dynamodb create-table \
--table-name tab1 \
--attribute-definitions \
AttributeName=col1,AttributeType=S \
AttributeName=col2,AttributeType=S \
--key-schema \
AttributeName=col1,KeyType=HASH \
AttributeName=col2,KeyType=RANGE \
--billing-mode=PAY_PER_REQUEST


※キーとして使用されない属性を定義するとエラーとなる
An error occurred (ValidationException) when calling the CreateTable operation:
One or more parameter values were invalid:
Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions


aws dynamodb describe-table --table-name tab1
aws dynamodb list-tables

-- 2. データ追加

aws dynamodb put-item \
--table-name tab1 \
--item \
'{"col1": {"S": "val11"}, "col2": {"S": "val12"}, "col3": {"S": "val13"}, "col4": {"N": "1"}}'

aws dynamodb put-item \
--table-name tab1 \
--item \
'{"col1": {"S": "val21"}, "col2": {"S": "val22"}, "col3": {"S": "val23"}, "col4": {"N": "2"} }'

aws dynamodb scan --table-name tab1

aws dynamodb describe-table --table-name tab1
※データを追加しただけでは、テーブル定義の属性には反映されない

 

-- 3. グローバルセカンダリインデックスを作成する
If you are adding a new global secondary index to the table, AttributeDefinitions must include the key element(s) of the new index.


aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind11\",\"KeySchema\":[{\"AttributeName\":\"col3\",\"KeyType\":\"HASH\"}], \
\"Projection\":{\"ProjectionType\":\"ALL\"}}}]"


aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind12\",\"KeySchema\":[{\"AttributeName\":\"col3\",\"KeyType\":\"HASH\"}], \
\"Projection\":{\"ProjectionType\":\"KEYS_ONLY\"}}}]"


aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind13\",\"KeySchema\":[{\"AttributeName\":\"col3\",\"KeyType\":\"HASH\"}], \
\"Projection\":{\"ProjectionType\":\"INCLUDE\",\"NonKeyAttributes\":[\"col4\"]}}}]"


aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col2,AttributeType=S \
AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind14\",\"KeySchema\":[{\"AttributeName\":\"col2\",\"KeyType\":\"HASH\"},{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}], \
\"Projection\":{\"ProjectionType\":\"ALL\"}}}]"

aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col2,AttributeType=S \
AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind15\",\"KeySchema\":[{\"AttributeName\":\"col2\",\"KeyType\":\"HASH\"},{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}], \
\"Projection\":{\"ProjectionType\":\"KEYS_ONLY\"}}}]"

aws dynamodb update-table \
--table-name tab1 \
--attribute-definitions AttributeName=col2,AttributeType=S \
AttributeName=col3,AttributeType=S \
--global-secondary-index-updates \
"[{\"Create\":{\"IndexName\": \"ind16\",\"KeySchema\":[{\"AttributeName\":\"col2\",\"KeyType\":\"HASH\"},{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}], \
\"Projection\":{\"ProjectionType\":\"INCLUDE\",\"NonKeyAttributes\":[\"col4\"]}}}]"

 

aws dynamodb describe-table --table-name tab1
aws dynamodb describe-table --table-name tab1 | grep IndexStatus

-- 4. グローバルセカンダリインデックスをクエリする
aws dynamodb query \
--table-name tab1 \
--index-name ind11 \
--key-condition-expression "col3 = :col3" \
--expression-attribute-values '{":col3":{"S":"val13"}}'

aws dynamodb query \
--table-name tab1 \
--index-name ind14 \
--key-condition-expression "col2 = :col2 and col3 = :col3" \
--expression-attribute-values '{":col2":{"S":"val12"},":col3":{"S":"val13"}}'


-- 5. グローバルセカンダリインデックスを削除する


aws dynamodb update-table \
--table-name tab1 \
--global-secondary-index-updates \
"[{\"Delete\":{\"IndexName\": \"ind11\"}}]"

 

aws dynamodb describe-table --table-name tab1 | grep IndexName


-- 6. クリーンアップ

-- テーブル一覧
aws dynamodb list-tables

-- テーブル削除
aws dynamodb delete-table --table-name tab1


(2) ローカルセカンダリインデックス

-- 1. テストテーブル作成

aws dynamodb create-table \
--table-name tab1 \
--attribute-definitions \
AttributeName=col1,AttributeType=S \
AttributeName=col2,AttributeType=S \
AttributeName=col3,AttributeType=S \
--key-schema \
AttributeName=col1,KeyType=HASH \
AttributeName=col2,KeyType=RANGE \
--billing-mode=PAY_PER_REQUEST \
--local-secondary-indexes \
"[{\"IndexName\": \"ind11\",
\"KeySchema\":[{\"AttributeName\":\"col1\",\"KeyType\":\"HASH\"},
{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}],
\"Projection\":{\"ProjectionType\":\"ALL\"}},
{\"IndexName\": \"ind12\",
\"KeySchema\":[{\"AttributeName\":\"col1\",\"KeyType\":\"HASH\"},
{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}],
\"Projection\":{\"ProjectionType\":\"KEYS_ONLY\"}},
{\"IndexName\": \"ind13\",
\"KeySchema\":[{\"AttributeName\":\"col1\",\"KeyType\":\"HASH\"},
{\"AttributeName\":\"col3\",\"KeyType\":\"RANGE\"}],
\"Projection\":{\"ProjectionType\":\"INCLUDE\",\"NonKeyAttributes\":[\"col4\"]}}
]"


aws dynamodb describe-table --table-name tab1

 

-- 2. データ追加

aws dynamodb put-item \
--table-name tab1 \
--item \
'{"col1": {"S": "val11"}, "col2": {"S": "val12"}, "col3": {"S": "val13"}, "col4": {"N": "1"}}'

aws dynamodb put-item \
--table-name tab1 \
--item \
'{"col1": {"S": "val21"}, "col2": {"S": "val22"}, "col3": {"S": "val23"}, "col4": {"N": "2"} }'

aws dynamodb scan --table-name tab1


-- 3. ローカルセカンダリインデックスをクエリする

aws dynamodb query \
--table-name tab1 \
--index-name ind11 \
--key-condition-expression "col1 = :col1 and col3 = :col3" \
--expression-attribute-values '{":col1":{"S":"val11"},":col3":{"S":"val13"}}'

aws dynamodb query \
--table-name tab1 \
--index-name ind12 \
--key-condition-expression "col1 = :col1 and col3 = :col3" \
--expression-attribute-values '{":col1":{"S":"val11"},":col3":{"S":"val13"}}'

aws dynamodb query \
--table-name tab1 \
--index-name ind13 \
--key-condition-expression "col1 = :col1 and col3 = :col3" \
--expression-attribute-values '{":col1":{"S":"val11"},":col3":{"S":"val13"}}'

※インデックスに射影した属性とベーステーブルのパーティションキー、ソートキーだけ表示される


-- 4. ローカルセカンダリインデックスを削除する

不可

 

-- 5. クリーンアップ

-- テーブル一覧
aws dynamodb list-tables

-- テーブル削除
aws dynamodb delete-table --table-name tab1