見出し画像

DynamoDBで'latest'を管理する

DynamoDBでシステムを開発する際、すべてのデータモデルにソートキーが必要になるわけではありません。場合によっては、パーティションキーだけで十分です。ソートキーのないテーブルでは、最新のアイテム(例えば、ドキュメントの最新バージョン)を追跡するのが難しい場合があります。本記事では、この課題に対する解決策を提供し、避けるべきアンチパターンについても解説します。

** You can read the English version here.

DynamoDBとは?

DynamoDBは完全マネージド型のNoSQLデータベースサービスで、高速かつ予測可能なパフォーマンスとシームレスなスケーラビリティを提供します。各アイテムはテーブル内でパーティションキーとオプションのソートキーによって一意に識別されます。

課題

DynamoDBテーブルがアプリケーションのバージョン管理されたドキュメントを保存するために設計されているとします。それぞれのドキュメントバージョンは、例えばdocumentVersionというパーティションキーで一意に識別されます。この場合、各ドキュメントバージョンはそれぞれ異なるため、ソートキーは必要ありません。そのため、このテーブルにはソートキーが存在しません。

課題は、アプリケーションがバージョンのIdentifierを知らずに最新のドキュメントバージョンを取得する必要がある場合に発生します。ソートキーがない場合、バージョンやタイムスタンプでアイテムをソートできないため、効率的に最新のドキュメントバージョンを取得するにはどうすればよいでしょうか?

解決策 ✅

解決策は、DynamoDBテーブルに特別なアイテムを追加し、latestというパーティションキーの値を持たせることです。このアイテムには最新のドキュメントバージョンと同じデータが保存されます。新しいドキュメントバージョンが追加されるたびに、このlatestアイテムを更新して新しいデータを反映させます。

この方法を使用することで、アプリケーションはlatestというパーティションキーを持つアイテムをクエリするだけで、最新のドキュメントバージョンを迅速に取得できます。

実装の詳細

新しいドキュメントバージョンを作成する

以下は、AWS SDK for Typescript (v3) を使用して新しいドキュメントバージョンを追加し、latestアイテムを更新する例です。

import { DynamoDBClient, TransactWriteItemsCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({ region: "your-region" });

async function addNewDocumentVersion(
  documentVersion: string, content: string
) {
  const newDocumentItem = {
    TableName: process.env.TABLE_NAME,
    Item: {
      documentVersion: { S: documentVersion },
      content: { S: content },
    },
  };

  const latestDocumentItem = {
    TableName: process.env.TABLE_NAME,
    Item: {
      documentVersion: { S: "latest" },
      content: { S: content },
      actualVersion: { S: documentVersion }
    },
  };

  const command = new TransactWriteItemsCommand({
    TransactItems: [
      {
        Put: newDocumentItem,
      },
      {
        Put: latestDocumentItem,
      },
    ],
  });

  try {
    await client.send(command);
    console.log("新しいドキュメントバージョンが追加され、'latest'が正常に更新されました。");
  } catch (error) {
    console.error("新しいドキュメントバージョンの追加中にエラーが発生しました:", error);
  }
}

ポイント

データの一貫性を確保するために、latestアイテムを更新する際には条件付き書き込みやトランザクションを検討してください。

latestDocumentItemのactualVersion属性には、ドキュメントの実際のバージョンが保存されています。特定のドキュメントバージョンを取得する際に、latestアイテムを取得してactualVersionと比較することで、それが最新かどうかを確認できます。

悪い解決策 ⛔

テーブルの設計において、パーティションキーに固定値を使用し、ソートキーにcreatedAtを含めることを検討する場合があります。この設計は、createdAtタイムスタンプを利用してアイテムを並べ替える意図があります。

しかし、このアプローチにはいくつかの問題があります:
• DynamoDBテーブルのパフォーマンスとスケーラビリティに悪影響を与える可能性がある。
• ソートキー用の不要な列を含んでしまう。