Amazon Web Services ブログ

Amazon DynamoDB 向け NoSQL Workbench を使用したデータモデリング



Amazon DynamoDB などの NoSQL データベースを使用する場合、リレーショナルデータベースで慣れているものとは異なる最適化を選択する傾向があります。リレーショナルデータベースの経験から、最初は別の方法で実行するように指示されていたため、簡単ではありませんでした。

これを支援するために、AWS は Windows および macOS で利用可能なクライアント側アプリケーションである Amazon DynamoDB 向け NoSQL Workbench をリリースしました。これを使用して、スケーラブルで高性能なデータモデルを構築し、クエリの開発とテストを簡素化できます。NoSQL Workbench を使用すると、次のことができます。

  • 1 つ以上のテーブルを使用してデータモデルを定義します。
  • データモデルを視覚化して、さまざまなシナリオでどのように機能するかを理解します。
  • 複数のプログラミング言語用のデータプレーン操作を構築します。

このブログ記事では、一般的に利用可能になった NoSQL Workbench を使用して、複数の顧客の URL ブックマークの管理という一般的なユースケースのデータモデルを設計しています。比較的ユースケースが単純な場合でも、多くの興味深い考慮事項があります。

データモデラー

このアプリケーションでは、ブックマークと顧客アカウントに関する情報を保存する必要があります。まず、保存したい属性のリストを、保存する予定の簡単な説明とともに書き留めます。

  • 顧客
    • customerId – ユニバーサル一意識別子 (UUID)
    • email
    • fullName ­– 例: “Shirley Rodriguez”
    • userPreferences – アプリのユーザー設定を記述する JSON オブジェクト
    • creationDate
    • updateDate
  • ブックマーク
    • URL – “https://…”
    • customerId – このブックマークを保存している顧客
    • folder – ブックマークを整理するためのフォルダ (例: “クラウド”)
    • title – デフォルトではページの HTML タイトル
    • description – オプション
    • creationDate
    • updateDate

最初のアプローチでは、リレーショナルデータベースで行うのと同様に、2 つのテーブルを作成します。1 つは顧客用、もう 1 つはブックマーク用です。customerId 属性は、2 つのテーブル間の情報をリンクします。このデザインを実際に見てみましょう。NoSQL ワークベンチのデータモデラーセクションを使用して、2 つのテーブルを持つ新しいデータモデルを作成します。

次のスクリーンショットは、顧客テーブルの詳細を示しています。

次のスクリーンショットは、ブックマークテーブルの詳細を示しています。

顧客テーブルには、プライマリキーとして customerId があります。ブックマークテーブルには、複合型プライマリキーを使用します。ここで、customerId はパーティションキー、url はソートキーです。このように、2 人の顧客が同じ URL を保存している場合、両方をテーブルに含めることができます。

DynamoDB には固定スキーマがありません。テーブルの作成時に定義する必要があるのは、プライマリキー (パーティションキーと任意のソートキー) の属性のみです。テーブルに保存されている各項目は、プライマリキーの属性に加えて、さまざまな属性を使用できます。

createDateupdateDate などの日付フィールドの場合、ISO 8601 標準を使用して、“20200325T091641.123” のように文字列として保存します。これには、文字列を比較して日付の順序が保持されるという利点があります。

userPreferences を JSON 文字列として保存します。簡単にするために、以下の例では空の JSON オブジェクト (例: “{}”) を使用しています。実際のアプリケーションに応じて、これを使用して言語やソート設定を保存できます。

{
  “language”: “en”,
  “sort”: “date”,
  “sortDirection”: “ascending”
}

2 つのテーブルを使用するこの最初のアプローチは、確実に機能します。しかし、顧客がブックマークを表示するためにログインすると、私のアプリケーションはどうなるでしょうか? アプリケーションは DynamoDB に対して毎回 2 つのリクエストを実行します。1 つ目は顧客テーブルの顧客データを取得するリクエストで、2 つ目はブックマークテーブルの顧客ブックマークを取得するリクエストです。

これは、リレーショナルデータモデルを変更せずに NoSQL に移動する場合によくあることです。テーブル結合は、データベースへの複数のリクエストに対して「アンロール」されます。これは効率的ではありません。1 つではなく 3 つ以上のリクエストが発生し始めた場合は特に非効率的です。

NoSQL データベースを使用する場合は、アプリケーションのアクセスパターンに合わせて最適化するようにデータモデルを設計する必要があります。ご自分で問いかけてみてください。

  • データを挿入するにはどうすればよいですか?
  • そのデータを更新するにはどうすればよいですか?
  • 情報を取得するためにどのようなクエリを使用しますか? どのくらいの頻度で行いますか?

これらの質問が明確でない場合は、データモデルの設計を始めないでください。そうでないと、データモデルを頻繁に更新するリスクがあるため、開発が遅くなります。

ブックマークアプリケーションに戻って、より良いデータモデルを設計できますか? できます!

特定の顧客について、ほとんどの場合、アプリケーションが顧客情報の要約と顧客のブックマーク一覧を表示していることがわかります。

このすべての情報を 1 つのクエリで取得できたらすばらしいと思いませんか? そのために、顧客情報と顧客のブックマークを、関連する項目のコレクションと同じテーブルに保存します。仕組みを見ていきましょう。

CustomerBookmark テーブルのプライマリキーは複合型です。パーティションキーは常に customerId ですが、ソートキーは異なる値を保持できます。ソートキーを使用してブックマークの URL を保存するか、“CUST#” などの連結文字列に続く顧客データの customerId を保存します。このように、ソートキーはオーバーロードされた属性であり、その一般的な名前として sk を使用しています。

顧客データのソートキーの一部として customerId を追加することは冗長ですが、このようにして sk 属性のカーディナリティは高いです (非常に珍しいか、一意の値が含まれることを意味します)。また、ホットパーティションを作成しなくても、後でセカンダリインデックスのパーティションキーとして使用できます。

NoSQL Workbench でテーブルを定義するときに、属性を 1 つ以上のファセットに割り当てることができます。ファセットは、NoSQL Workbench の仮想構成要素であり、DynamoDB 自体の機能的な構成要素ではないため、同じテーブルに保存するさまざまな種類のデータを視覚化できます。ファセットごとに、パーティションキーとソートキーのエイリアスを構成できます。オーバーロードされた属性の場合、エイリアスは、その属性がそのファセットに対して保持することになっている内容を記述します。

私の場合、CustomerBookmark テーブルには、項目に保存されているデータに応じて、顧客データとブックマークの 2 つのファセットがあります。2 つのファセットのそれぞれには、sk ソートキーの異なるエイリアスがあります。顧客データを保存する項目のタイプ、ブックマーク情報を保存する項目の url です。次のセクションでファセットの使用方法を説明します。

これらの関連項目を同じインデックスに一緒に保存しているので、アプリケーションは customerId によって単一のクエリを実行し、必要なすべての情報 (顧客データとブックマーク) を取得できます。ビジュアライザーを使用してこれを明確にしてみましょう。

ビジュアライザー

この新しいアプローチの利点を文字通り「見る」ために、NoSQL Workbench のビジュアライザーセクションに移動します。ビジュアライザーを使用する利点の 1 つは、サンプルデータを追加して視覚化を強化できることです。

具体的には、作成したグローバルセカンダリインデックス (GSI) の観点からサンプルデータを表示することもできます。

  • E メールアドレスで顧客データを取得する ByEmail インデックス。ブックマーク情報をホストしている項目など、E メール属性のない項目は、インデックスによって取得されないのでご注意ください。
  • ブックマークデータを URL で取得するための ByUrl インデックス。複数の顧客が同じ URL をブックマークできるため、インデックスのソートキーとして customerId を追加したことにご注意ください。
  • ByCustomerFolder インデックスを使用して、顧客ごとに、フォルダごとにブックマークを取得します。

CustomerBookmark テーブルのファセットを選択すると、項目が顧客またはブックマークデータをホストしているときにデータがどのようにレンダリングされるかがわかります。

  • 顧客ファセットには、E メールアドレスや氏名などの顧客情報が表示されます。ソートキーは type エイリアスを使用しており、最初の文字が “CUST#” です。
  • ブックマークファセットは、フォルダやタイトルなどの値を持つブックマークデータを記述します。ソートキーは url エイリアスを使用しており、最初の文字が “CUST#” ではありません。

DynamoDB ローカルの使用

DynamoDB ローカルを使用して、ローカル開発環境で DynamoDB アプリケーションを開発してテストできます。このように、インターネットに接続していなくても、ローカルでアプリケーションを操作できます。以下の手順通りに、ノート型パソコンに DynamoDB ローカルをダウンロードしてセットアップします。必要に応じて、Apache Maven または Docker イメージを使用できます。

アーカイブを解凍したディレクトリで、DynamoDB ローカルを起動します。

java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

別のウィンドウで、AWS コマンドラインインターフェイス (CLI) を使用してローカルエンドポイントが機能することをテストします。

aws dynamodb list-tables --endpoint-url http://localhost:8000

{
    "TableNames": []
}

予想どおり機能しており、現在テーブルはありません。

NoSQL Workbench ビジュアライザーで、データモデルを DynamoDB にコミットすることを選択して、新しい DynamoDB ローカル接続を追加します。

その後、前の AWS CLI コマンドを繰り返して、ローカルで使用可能な DynamoDB テーブルを一覧表示します。これで、CustomerBookmark テーブルが表示されます。

aws dynamodb list-tables --endpoint-url http://localhost:8000

{
    "TableNames": [
        "CustomerBookmark"
    ]
}

すべてのサンプルデータがテーブルに追加されました。簡単なチェックを行うためにテーブルスキャンを実行します。簡潔にするために、ここでは結果を示していません。

aws dynamodb scan --table-name CustomerBookmark --endpoint-url http://localhost:8000

オペレーションビルダー

NoSQL Workbench のオペレーションビルダーセクションに移動して、DynamoDB ローカルまたは実際の AWS アカウントを使用して、接続した状態で操作を構築して実行できます。テーブル内の項目の配置、更新、削除、またはテーブルやインデックスのクエリやスキャンを行う操作を構築できます。トランザクションのサポートもあります。

オペレーションビルダーを使用して、アプリケーションが実行する操作をシミュレートし、Python、JavaScript (Node.js)、または Java 向けのコードを生成できます。条件とパラメータを使用して、データをフィルター処理したり、インデックスを前方または後方にスキャンしたり、評価する項目の数を制限したりできます。

たとえば、ブックマークアプリケーションをシミュレートするには、CustomerBookmark テーブルで単一のクエリ操作を実行して、特定の customerId のすべての情報 (顧客データとブックマーク) を取得します。

DynamoDB ローカル接続でクエリを実行すると、サンプルデータから期待通りの情報が得られます。

追加の調整として、[インデックス形式をスキャンする] オプションを使用してクエリのソート順序を変更し、最初の項目として顧客データを取得できます。小文字の文字列 “cust#” などを使用して、顧客データを識別するために sk ソートキーで使用するプレフィックスを変更しても、同じ結果を得ることができます。

結果に満足したので、アプリケーションを開始するコードを生成するオプションを選択します。この操作では、出力プログラミング言語として Python を選択します。このスクリーンショットに表示されるコードは、生成されている結果のサブセットに過ぎません。

同様に、オペレーションビルダーを使用してセカンダリインデックスをクエリできます。たとえば、ByUrl インデックスを選択して特定のウェブサイトをブックマークした顧客の数を確認できます。

ここでも、サンプルデータに対してクエリを実行して結果を検証することができます。

最後に、ByUrl セカンダリインデックスを使用してクエリのコードを生成します。今回は、出力プログラミング言語として Java を選択します。

まとめ

DynamoDB 向け NoSQL Workbench は、アクセスパターンに基づいてデータモデルの設計を改善し、アプリケーションの実装を開始するコードを生成する際に役立ちました。DynamoDB ローカルを使用して、インターネット接続を必要とせずに実験できます。

NoSQL Workbench は、IAM ロールと一時的な AWS セキュリティ認証情報もサポートしています。たとえば、組織で AWS Single Sign-On (SSO) を使用している場合、ユーザーは Active Directory、組み込みの AWS SSO ディレクトリ、または AWS SSO に接続されている別の ID プロバイダーにサインインできます。その ID を、NoSQL Workbench での認証に使用できる IAM ロールにマップします。

DynamoDB 向け NoSQL Workbench が一般公開になり、実際のアプリケーションでアイデアを変換するのがはるかに簡単になりました。まず、ここから NoSQL Workbench をダウンロードして、何に使用するのか教えてください。

 


著者について

Danilo Poccia

Danilo Poccia は、あらゆる規模のスタートアップ企業や企業と協力して、イノベーションをサポートしています。アマゾン ウェブ サービスのプリンシパルエバンジェリストとして経験を積んできました。サーバーレスアーキテクチャとイベント駆動型プログラミング、および機械学習とエッジコンピューティングの技術的影響やビジネスへの影響に焦点を当て、人々がアイデアを実現できるよう支援するためにその経験を活かしています。Manning の AWS Lambda in Action の著者です。Twitter で @danilop をフォローしてください。