LoginSignup
5
2

More than 3 years have passed since last update.

DynamoDB で、条件付き更新 と トランザクション を組み合わせて、UNIQUE 制約を実現する方法

Posted at

はじめに

現状、DynamoDB では、 RDB で言うところのUNIQUE制約がありません。つまり「UserテーブルでEmailを一意になるように制約をかける」といったことができません。

正確に言うと、ハッシュキー属性にはUNIQUE制約があります。
この記事では、ハッシュキーにはUNIQUE制約があることを利用しつつ、条件付き更新トランザクション を組み合わせて、任意の属性を対象とするUNIQUE制約を実現する方法を紹介しています。

以下のようなDynamoDBの知識を前提としています。

  • 項目 と 属性 がなにを指しているのか理解している
  • hash-key(とrange-key) を理解している
  • 基本的な CRUD 関連の操作方法を理解している
  • 条件付き更新を理解している
  • トランザクションを理解している

必要に応じて、以下の AWS のドキュメントを参照してください。

UNIQUE制約の実現方法

例えば、以下のような User エンティティがあるとします。

diagram-4658271672369125146.png

User エンティティをDynamoDBに新規作成する場合、以下の項目を作成する処理をトランザクションで実行します。

  • User エンティティ自体を保存する項目(エンティティ項目)
  • UserのEmail属性を UNIQUE属性にするための項目(UNIQUE制約用項目)

エンティティ項目 では、EmailやNameなどのエンティティ自体の情報を記録します。
UNIQUE制約用項目 では、UNIQUE制約をかけたい項目をhash-keyとして設定し、条件付き更新で試みます。

例として、Emailに対してUNIQUE制約をかけたい場合を考えます。このとき、UNIQUE制約用項目を以下の手順で作成します。

  1. PK(hash-key) を User#Email#test@example.com という値で設定。
  2. if attribute_not_exists(PK) で、書き込みを試みる。

以下の図は、UNIQUE制約に引っかかってエラーが起こる場合を示しています。

dynamodb-timeline-summary.png

Bob が test@example.com で項目を作成した後に、Alice が test@example.com で項目を作成しようとして失敗します。 Aliceが書き込むときには if attribute_not_exists(PK) の条件が偽になるからです。

トランザクションで実行された場合、ロールバックが実行され、Aliceの項目作成処理がキャンセルされます。

このようにして、UNIQUE制約を実現しています。

更新と削除の処理について

上記は、新規作成時の処理について解説しました。更新と削除のときにも注意が必要です。
それぞれ以下のような処理を行います。

更新時

更新の場合は、Emailの値を変更する場合のみ UNIQUE制約について考慮する必要があります。
以下の更新処理をトランザクションで実行します。

  • エンティティ項目のEmail属性の値を更新する
  • 新しいEmailについて、if attribute_not_exists(PK) という条件で書き込みを試みる
  • 古いEmailについて、UNIQUE制約用項目を削除する

削除時

削除の場合は、以下の処理をトランザクションで実行します。

  • エンティティ項目を削除する
  • UNIQUE制約用項目を削除する

まとめ

現状、DynamoDBでは任意の属性に対してUNIQUE制約をかけることができないので、条件付き更新 と トランザクションを組み合わせて擬似的に実現する方法を紹介しました。

「hash-key に設定できないけどUNIQUE制約を設定したい属性がある」といった場合に、有効な方法であると考えています。デメリットとしては、実装が少し複雑になってしまうところでしょうか。

DynamoDBは、アップデートされるごとに機能が増えたり、機能の制約が緩和されたりするので、将来的に UNIQUE制約を設定できる可能性もあるかもしれません。そうなった場合は、この方法は不要になるでしょう。

5
2
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
5
2