DynamoDB でのユニークキー生成方法 ~アトミックカウンタもしくは UUID で実現〜

記事タイトルとURLをコピーする

はじめに

データベースでレコードを管理するとき、レコードごとにユニークなキーを設定しておきたい場面は多々ありますよね。

例えば、MySQL の場合は AUTO_INCREMENTのような自動シーケンス機能を使うことで連番を割り当ててくれます。 しかし、DynamoDB にはそのような機能はありません。

では DynamoDB でユニークキーを設定するにはどうすればいいのでしょうか。
ということで、今回は「アトミックカウンタを使った連番管理」と「UUID を使った一意なキーの生成」の2つの具体的な実装方法をサンプルコード(Python)とともに紹介します。

アトミックカウンタによる連番管理

DynamoDB のアトミックカウンタを使って、連番を管理する方法を紹介します。 アトミックカウンタを使うことで、同時に複数のプロセスからアクセスがあっても、正確に一意な連番を生成できます。

参考:https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.AtomicCounters

アトミックカウンタの Python サンプルコード

DynamoDB の UpdateItem 操作を使って、カウンタ値をインクリメントします。

参考:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_item.html

import boto3

table_name = "dynamodb_table_name"
counter_key = "counter_key"
dynamodb_client = boto3.client("dynamodb")


def increment_counter():
    # カウンタをインクリメントして更新する
    response = dynamodb_client.update_item(
        TableName=table_name,
        Key={
            "id": {"S": counter_key}  # カウンタ用アイテムのキー
        },
        UpdateExpression="SET #val = if_not_exists(#val, :start) + :inc",
        ExpressionAttributeNames={
            "#val": "counter_value"  # カウンタ値を保持するフィールド
        },
        ExpressionAttributeValues={
            ":inc": {"N": "1"},  # インクリメントする値
            ":start": {"N": "0"}  # 初期値
        },
        ReturnValues="UPDATED_NEW"
    )

    # 更新後のカウンタ値を取得可能
    new_counter_value = response["Attributes"]["counter_value"]["N"]
    return new_counter_value

new_id = increment_counter()
print(f"New Counter ID: {new_id}")

UUID によるユニークキーの生成

UUID(Universally Unique Identifier)は、一意性を保証するためのランダムな識別子で、世界中のシステム間で衝突する可能性が非常に低いためよくユニークキーとして利用されます。 Pythonの標準ライブラリには、UUID を生成するための機能が含まれており、特別なインストールは必要ありません。

UUID は 128 ビットの識別子で、通常は 16 進数表現で表されます。 これを数値型に変換したり、部分的に利用することで、DynamoDB に適用することが可能です。

UUID の基本的な生成方法

Python で UUID を生成するには、標準ライブラリの uuid モジュールを使用します。 以下のコードだと、24cc08f8-1f58-4983-8de3-7598ffefa5b1 のような 36 文字の ID が生成されます。

参考:https://docs.python.org/ja/3/library/uuid.html

import uuid

# UUIDを生成
unique_id = str(uuid.uuid4())

UUID の Python サンプルコード

DynamoDB のカラムが数値型である場合、UUID をそのまま利用するのではなく、数値に変換して使うこともできます。 数値に変換すると 43009895629459701174015780120016914245 のような形で長い数字列になるため、以下のコードでは桁数を 12 桁に制限して使う例を示します。

import uuid
import boto3

table_name = "your-dynamodb-table"
dynamodb_client = boto3.client("dynamodb")


def insert_item_to_dynamodb():
    # UUIDを生成
    unique_id = uuid.uuid4()  # 例:327925c6-5b1b-4815-9988-8a303e320e4d
    num_unique_id = unique_id.int % (10**12)  # 例:468322877005
    
    # 挿入データ
    item = {
        "id": {"S": num_unique_id},
        "SID": {"S": "Content Cell"},
        "lbc": {"S": "Content Cell"}
    }

    # DynamoDBにデータを挿入
    dynamodb_client.put_item(TableName=table_name, Item=item)

insert_item_to_dynamodb()

まとめ

本記事では、DynamoDB におけるユニークキー生成のための2つのアプローチを紹介しました。 ユースケースに応じて、UUID やアトミックカウンタのどちらか、または両方を選択して活用してください。

連番の管理が重要で、複数のプロセスからの同時アクセスが多い場合はアトミックカウンタを、システム全体でユニークな識別子が必要で、連番である必要がない場合は UUID というように使い分けるといいかもしれませんね。

この記事がどなたかのお役に立てれば幸いです。

香取 拓哉 (記事一覧)

2023年度新卒入社

アプリケーションサービス部ディベロップメントサービス3課所属