LoginSignup
28
16

More than 1 year has passed since last update.

【初心者】Amazon DynamoDB LSI/GSI を使ってみる

Last updated at Posted at 2021-05-04

1. 目的

  • AWSのデータベース関連サービスの復習をしている。DynamoDBについて、LSI/GSIがなんだかよく分からなかったため、これを機に動作確認する。

2. やったこと

  • 練習用のDynamoDBテーブルを作成する。
  • LSI/GSIを設定し、それらを用いてどのようなクエリができるのかを確認する。

3. 構成図

  • EC2インスタンス内のPythonスクリプトからクエリを実行する。

dynamo07.png

  • 練習用のDynamoDBテーブルの内容は以下の通り。(野菜・果物分類表的なイメージ)

dynamo06.png

4. 予習

5. 実機確認

5.1 DynamoDB テーブルとGSI/LSIの作成

  • DynamoDBテーブル「mksamba-qiita」を作成する。パーティションキーを「Name」、ソートキーを「Color」とし、その組み合わせをプライマリーキーとする。

dynamo01a.png

  • LSIを作成する。
    • LSIの場合、パーティションキーはプライマリーキーで使用したものと同じ「Name」である必要がある。
    • ソートキーを「Kind」とする。
    • 「ローカルセカンダリインデックスとしての作成」にチェックを付ける。チェックを付けないとGSIになってしまう。

dynamo02a.png

  • GSIを作成する。
    • パーティションキーはプライマリーキーで使用したものとは別の「Country」とする。

dynamo03a.png

  • LSI/GSIが設定されていることを確認し、テーブルを作成する。

dynamo04a.png

  • 作成したテーブルにデータを入力する。

dynamo05a.png

5.2 クエリの動作確認

  • 「Name」が「Apple」の項目(行)を取得する。
    • 「Name」がパーティションキーのため実行OK。2つヒットする。
query1.py
import boto3
from boto3.dynamodb.conditions import Key

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("mksamba-qiita")
response = table.query(
    KeyConditionExpression=Key("Name").eq("Apple")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query1.py
[{'Season': 'Winter', 'Color': 'Green', 'Country': 'NZ', 'Kind': 'Fruit', 'Name': 'Apple'}, {'Season': 'Winter', 'Color': 'Red', 'Country': 'Japan', 'Kind': 'Fruit', 'Name': 'Apple'}]
  • 「Name」が「Apple」で、「Color」が「Red」の項目(行)を取得する。(Pythonコードはクエリ部分のみ記載)
    • 「Color」がソートキーのため実行OK。1つヒットする。
query2.py
response = table.query(
    KeyConditionExpression=Key("Name").eq("Apple") & Key("Color").eq("Red")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query2.py
[{'Season': 'Winter', 'Color': 'Red', 'Country': 'Japan', 'Kind': 'Fruit', 'Name': 'Apple'}]
  • 「Name」が「Apple」で、「Kind」が「Fruit」の項目(行)を取得する。
    • 「Kind」がソートキーではないため、実行エラー。
query3.py
response = table.query(
    KeyConditionExpression=Key("Name").eq("Apple") & Key("Kind").eq("Fruit")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query3.py
Traceback (most recent call last):
  File "query3.py", line 8, in <module>
~~
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Query operation: Query condition missed key schema element: Color
  • 「Name」が「Apple」で、「Kind」が「Fruit」の項目(行)をクエリ時にLSIを指定して取得する。
    • 「Kind」がLSIのソートキーになっているため、実行OKになる。2つヒットする。
query4.py
response = table.query(
    IndexName='Name-Kind-index', KeyConditionExpression=Key("Name").eq("Apple") & Key("Kind").eq("Fruit")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query4.py
3 [{'Season': 'Winter', 'Color': 'Green', 'Country': 'NZ', 'Kind': 'Fruit', 'Name': 'Apple'}, {'Season': 'Winter', 'Color': 'Red', 'Country': 'Japan', 'Kind': 'Fruit', 'Name': 'Apple'}]
  • 「Country」が「Japan」の項目(行)を取得する。
    • 「Country」がパーティションキーでないため、実行エラーになる。
query5.py
response = table.query(
    KeyConditionExpression=Key("Country").eq("Japan")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query5.py
Traceback (most recent call last):
  File "query5.py", line 8, in <module>
~
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Query operation: Query condition missed key schema element: Name
  • 「Country]が「Japan」の項目(行)をクエリ時にGSIを指定して取得する。
    • GSIにおいては「Country」がパーティションキーのため、実行OK。3つヒットする。
query6.py
response = table.query(
    IndexName='Country-index', KeyConditionExpression=Key("Country").eq("Japan")
)
print(response["Items"])
[ec2-user@ip-10-0-0-232 ~]$ python3 query6.py
[{'Season': 'Winter', 'Color': 'Orange', 'Country': 'Japan', 'Kind': 'Vegetable', 'Name': 'Carrot'}, {'Season': 'Winter', 'Color': 'Red', 'Country': 'Japan', 'Kind': 'Fruit', 'Name': 'Apple'}, {'Season': 'Summer', 'Color': 'Red', 'Country': 'Japan', 'Kind': 'Vegetable', 'Name': 'Tomato'}]

6. 所感

  • 使いこなせる感はないが、何となく設定する意味は分かるようになった。
28
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
16