DynamoDB でシーケンスを管理する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

DynamoDB でテーブル設計をしていると、プライマリキーをシーケンスを使って登録したい場合ってあると思います。
今のところ DynamoDB では MySQL の Auto Increment のような機能がないため、採番用のテーブルを作ってそこから発番するのがよく使われる手法とのことでした。
自分でも試した結果を残しておきます。(Ruby)

シーケンス管理用テーブル

最初にテーブル定義情報を記しておきます。

テーブル名:sequences
説明:各テーブルに連番を発行するための管理テーブル。current_number 属性はアトミックカウンタとして扱う。

Attribute プライマリーキー 説明
name String ◯(Hash Key) 対象テーブルの名前
current_number Number 現在のシーケンスの値

初期データとして、以下の Item を登録しておきます。

Attribute データ
name my_table
current_number 0

シーケンス発行の例(抜粋)

def dynamodb
  @dynamodb ||= Aws::DynamoDB.new(region: YOUR_REGION, endpoint: YOUR_ENDPOINT)
end
 
def next_id(table_name)
  data = dynamodb.update_item(
           table_name: 'sequences',
           key: {
             'name' => {
               s: table_name
             },
           },
           attribute_updates: {
             'current_number' => {
               value: {
                 n: '1'
               },
               action: 'ADD',
              },
           },
           return_values: 'UPDATED_NEW',
           ).data

  data['attributes']['current_number'][:n]
end

…

# シーケンス発行
id = next_id('my_table')
# アイテムを登録する
…

update_item の ADD で current_number の値をインクリメントしつつ、UPDATED_NEW で更新後の値を返却します。
※DynamoDB の操作部分は Ruby に関わらず、他の言語でも基本的には変わらないです。

まとめ

DynamoDB でのシーケンスはアトミックカウンタを使って簡単に実装することが出来ました。
また、似たような自動発行系として現在日時を登録したいユースケースがあると思いますが、
こちらは DynamoDB を操作するアプリ上から発行して登録するのが一般的なようです。(自分もそうしてます)