Open3

DynamoDB入門

orbitryotaorbitryota

DynamoDBを触りながら理解する

サンプル

  • sampleTable

    • PartitionKey(パーティションキー):Id(String)
    • SortKey:timestamp(Number)
  • CDKソースコード

    // DynamoDB
    const sampleTable = new Table(this, 'sampleTable', {
      tableName: "sampleTable",
      partitionKey: { name: 'Id', type: AttributeType.STRING },
      sortKey: { name: 'timestamp', type: AttributeType.NUMBER },
      ...
    });
    sampleTable.addLocalSecondaryIndex({
      indexName: "hoge",
      sortKey: { name: "hoge", type: AttributeType.STRING },
    });
SELECT * FROM "sampleTable"
Id timestamp hoge
2 1633046400001
1 1633046400000
1 1633046400001 test
1 1633046400002

ORDER BY の制約

WHERE句でパーティションキーをフィルタするとORDER BYできる

SELECT * FROM "sampleTable" WHERE "Id" = '1' ORDER BY "timestamp"
Id timestamp hoge
1 1633046400000
1 1633046400001 test
1 1633046400002

WHERE句を指定しないとORDER BYできずにエラー

SELECT * FROM "sampleTable" ORDER BY "timestamp"

エラー

ValidationException: Must have WHERE clause in the statement when using ORDER BY clause.

WHERE句を複数指定してもORDER BYできずにエラー

SELECT * FROM "sampleTable" WHERE "Id" = '1' OR "Id" = '2' ORDER BY "timestamp"

エラー

ValidationException: Must have hash key in ORDER BY clause when more than one hash key condition specified in WHERE clause.

理由

  • ORDER BYは必ずPartition Keyと組み合わせて使用する必要がある
    • DynamoDBはORDER BYを実行する際、データを効率的に取得するため、特定のPartition Key内のデータに限定される。WHERE句でPartition Key(例: Id)を指定しない場合、DynamoDBはどの範囲をソートするべきか判断できず、エラーが発生する
  • 全データソートはDynamoDBではサポートされていない
    • DynamoDBは分散型のNoSQLデータベースであり、全データをソートする設計にはなっていない
    • 全データを対象にソートしたい場合は、データを取得後にアプリケーション側でソートする必要がある
orbitryotaorbitryota

WHEREの制約

WHEREの複数指定

できる。

SELECT * FROM "sampleTable" WHERE "Id" = '1' OR "Id" = '2'
Id timestamp hoge
2 1633046400001
1 1633046400000
1 1633046400001 test
1 1633046400002

PKでもSKでもGS(セカンダリインデックス)でもないキーの指定

できる。

※hogeはLSI(ローカルセカンダリインデックス)

Id timestamp hoge huga
2 1633046400001
2 1633046400002 test
2 1633046400003 test
1 1633046400000
1 1633046400001 test
1 1633046400002
1 1633046400003 test2
1 1633046400004 test
SELECT * FROM "sampleTable" WHERE huga = 'test'
Id timestamp hoge huga
2 1633046400003 test
1 1633046400004 test
orbitryotaorbitryota

INSERTの制約

PK(パーティションキー)のみ もしくは SK(ソートキー)のみを指定

PKのみ指定

INSERT INTO "sampleTable" VALUE {
  'Id': '1',
} 

エラー

ValidationException: Key attribute should be present in the item: Key timestamp

SKのみ指定

INSERT INTO "sampleTable" VALUE {
  'timestamp': 1633046400000
} 

エラー

ValidationException: Key attribute should be present in the item: Key Id

既存のソートキーと重複

Id timestamp hoge
2 1633046400001
1 1633046400000
1 1633046400001 test
1 1633046400002
INSERT INTO "sampleTable" VALUE {
  'Id': '1',
  'timestamp': 1633046400000
} 

エラー

DuplicateItemException: Duplicate primary key exists in table