🦔

DynamoDB の attribute_not_exists で重複登録を防ぐ方法

に公開

はじめに

DynamoDB でアプリケーションを作っていると、「同じ ID を持つアイテムが二重に登録されてしまうのを防ぎたい」 というシーンがよく出てきます。

RDB なら UNIQUE 制約 を設定できますが、DynamoDB にはそういった仕組みがありません。
そこで活躍するのが 条件付き書き込み (Conditional Write) と、その中で使える関数 attribute_not_exists です。

attribute_not_exists とは?

attribute_not_exists(属性名) は、指定した属性が存在しないときに true を返す関数です。
つまり 「まだこの属性が登録されていないなら処理を進めてOK」 という条件を表現できます。

これを DynamoDB の書き込み系オペレーション (PutItem / UpdateItem / DeleteItem) に組み込むと、条件を満たしたときだけ書き込みが行われる ようになります。

例: PutItem の上書きを防ぐ

通常、DynamoDB の PutItem は「同じプライマリキーが存在すれば上書き」という挙動になります。

aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json

上記のように実行すると、Id=456 がすでに存在していれば、そのアイテムを丸ごと上書きしてしまいます。

そこで条件式を追加します。

aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)"

この場合の動作は以下の通りです。

  • Id=456 が存在しない → 新規作成成功
  • Id=456 がすでに存在する → 条件式が false → エラー (ConditionalCheckFailedException)

これにより、誤って既存のアイテムを上書きしてしまうことを防げます。

複合キーの場合

テーブルが パーティションキー + ソートキー の複合キー構成になっている場合は、attribute_not_exists(pk) と attribute_not_exists(sk) の両方を満たす必要があります。

つまり 「同じ pk と sk の組み合わせが存在しないときだけ追加可能」 というユニーク性を担保できます。

ユースケース

  • ユーザー登録の重複防止:すでに存在するユーザーIDを再度作成しないようにする。
  • ユニーク制約の実現:DynamoDB は SQL のように UNIQUE 制約を持たないため、その代替として使える。
  • 楽観ロックの一部:attribute_exists と組み合わせて「属性が存在している場合だけ更新」といった制御も可能。

まとめ

  • attribute_not_exists(attr) は「属性がまだ存在しないとき」にだけ true になる。
  • これを条件付き書き込みに使うことで、重複登録や上書きを防げる。
  • 複合キーの場合は pk と sk の両方が存在しないことをチェックする。
  • DynamoDB でユニーク制約を実現するうえで欠かせない機能。

参考

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html

Discussion