カルキチブログ

DynamoDBの基本についてまとめてみた【初心者向け】

いま携わっている開発で初めてDynamoDBを触ったのですが、色々不明点が多かったのでまとめてみることにしました。

今までRDBMSしか使った開発しかやったことがなく、NoSQLに関してはほとんど知見がなかったので、かなり基本的なことしか書いていないです。

DynamoDBとは?

DynamoDBとは、AWSが提供するキーバリュー型のNoSQLデータベースです。

以下公式の引用です。

Amazon DynamoDB は、ハイパフォーマンスなアプリケーションをあらゆる規模で実行するために設計された、フルマネージド、サーバーレスの key-value NoSQL データベースです。DynamoDB は、内蔵セキュリティ、継続的なバックアップ、自動化されたマルチリージョンでのレプリケーション、インメモリキャッシング、データエクスポートツールを提供します。

引用: https://aws.amazon.com/jp/dynamodb/

DynamoDBを理解するのに必要に感じた用語

DynamoDBを理解するのに必要に感じた用語を簡単にですが、まとめてみました。

NoSQL(Not Only SQL)

NoSQLとは、Not Only SQLの略でSQLを使わずにデータの操作を行うデータベースです。

RDBMS(リレーショナル・データベース・マネジメント・システム)以外のデータベースはこのNoSQLに分類されます。

NoSQLには以下のような特徴があります。

  • 高速な処理が可能
  • システムの拡張・分散性にすぐれている(サーバーの台数を増やし水平分散によるスケールアップが可能)
  • データ構造の変更がRDBMSよりは容易

RDBMSは、データを表に似た構造で管理するデータベースのことを指します。

MySQLとかPostgre SQL(ポスグレ)とかが有名ですね!

NoSQLは大きく分けると以下の4種類に分類されます。

  • キーバリュー型: キーとバリューの組み合わせで情報を管理する(例: DynamoDB・Redis)
  • ドキュメント指向型: JSONやXMLなどのドキュメントで情報を管理する(例: MonogoDB)
  • カラム指向型:列単位で情報を管理する
  • グラフ指向型: データとデータ間のつながりを管理するモデル

今回の題材であるDynamoDBはキーバリュー型に該当するデータベースです。

アイテム

RDBMSでいうレコードに相当するものです。

一つのアイテムの最大上限は400KBです。

DynamoDB の項目の最大サイズは 400 KB で、属性名のバイナリの長さ (UTF-8 の長さ) と属性値の長さ (こちらもバイナリの長さ) を含みます。属性名はサイズ制限に反映されます。

引用: https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ServiceQuotas.html

プライマリキー

プライマリキー(主キー)はRDBMSにもありますが、DynamoDBのプライマリキーはRDBMSとちょっと勝手が違います。

DynamoDBのプライマリキーは、パーティションキー、またはパーティションキーとソートキーの複合キーのことを指します。

またはという部分がややこしいのですが、DynamoDBのプライマリキーは2種類の指定方法があります。

  • パーティションキーのみ指定する場合
  • パーティションキーとソートキー2つのキーを指定する場合

パーティションキー

プライマリキーの構成要素の1つとなるキーのことで、設定は必須です。

DynamoDBでは、テーブルのアイテムをパーティションと呼ばれる領域に保持しているのですが、アイテムがどのパーティションに保存されるかはパーティションキーによって決定されます。

古い情報だとハッシュキーと呼ばれていることもあります。

ソートキー

範囲の指定やソートを行うために必要なキーで、設定は任意です。

DynamoDBではデフォルトの状態では、ソートキーに指定した属性情報以外で範囲の指定やソートなど、データの検索を行うことができません。

古い情報だとレンジキーと呼ばれていることもあります。

セカンダリインデックス

プライマリキー以外の属性で、データに効率的にアクセスできるようにする仕組みのことです。

DynamoDBでは、テーブル作成時に指定したキーとは異なるパーティションキー・ソートキーを指定するもできます。

ソートキーの項で触れましたが、DynamoDBはデフォルトの状態だとソートキーでしかデータの絞り込みを行うことができないので、ソートキー以外でデータの絞り込みを行う際はセカンダリインデックスを使用することになります。

セカンダリインデックスには以下の2種類があります。

  • グローバルセカンダリインデックス
  • ローカルセカンダリインデックス

グローバルセカンダリインデックス(GSI)

テーブル作成時に設定したパーティションキー・ソートキーとは、別のパーティションキー・ソートキーを設定することができる仕組みのことをグローバルセカンダリインデックスと呼びます。

以下の図はAWSの公式の引用です。

引用: https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html#GSI.scenario

パーティションキーとソートキーは以下のように設定されています。

  • パーティションキー・・・UserId
  • ソートキー・・・GameTitle

今のテーブル設計で、ゲームごとの最高スコアを出す機能を実装することになったとします。

ソートキーにはGameTitleが設定されているわけですが、ゲームをタイトル順に並べ替えることしかできない今の状態だと、ゲームごとの最高スコアを出すことは難しいです。

このように、デフォルトのパーティションキー・ソートキーだけだとデータの絞り込みが難しいときに、グローバルセカンダリインデックスは役に立ちます。

以下のようにパーティションキーとソートキーを設定したGameTitleIndexというグローバルセカンダリインデックスの作成を行います。

  • パーティションキー・・・GameTitle
  • ソートキー・・・TopScore

引用: https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html#GSI.scenario

GameTitleIndexというグローバルセカンダリインデックスを作成することで、ゲームのトップスコアでソートできるようになったので、ゲームごとの最高スコアを効率よく出せそうです!

グローバルセカンダリインデックスを使うと、デフォルトで設定したものとは異なるパーティションキー・ソートキーを設定できるので、データを効率よく算出することができるようになります。

ローカルセカンダリインデックス(LSI)

デフォルトで設定したパーティションキーはそのままの状態にして、ソートキーだけデフォルトで設定したものとは別のキーを設定することができる仕組みのことをローカルセカンダリインデックスと呼びます。

以下の図もAWSの公式の引用です。

引用: https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html#LSI.Scenario

パーティションキーとソートキーは以下のように設定されています。

  • パーティションキー・・・ForumName
  • ソートキー・・・Subject

S3というフォーラムで過去1か月以内に更新されたスレッドを検索したいという要望が出たとします。

今のキー設計だと、スレッドごとの並び替えしかできないので、更新期間でデータの絞り込みを行うことはできません。

そこで以下のようにキーを設定したLastPostIndexというローカルセカンダリインデックスを作成します。

  • パーティションキー・・・ForumName
  • ソートキー・・・LastPostDateTime

LastPostIndexというローカルセカンダリインデックスを作成することで、特定のフォーラムで過去1か月以内に更新されたスレッドを検索することができそうです。

ちなみにですが、グローバルセカンダリインデックスとは以下の点が異なります。

  • ソートキーのみ新しく設定する必要があり、パーティションキーに関してはテーブル作成時に指定したものを使用する
  • テーブル作成後の追加はできない(グローバルセカンダリインデックスは後から設定できる)
  • 結果整合性、強い整合性両方をサポートしている(グローバルセカンダリインデックスは結果生合成)

テーブル作成後の追加はできない点と強い整合性をサポートしている点が特に重要なのかなと思いました、

強い整合性が必要な場合は、ConsistentReadというパラメータを有効にすると強い整合性が担保されるそうです。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html

まとめ

ではまとめです。

  • DynamoDBとはAWSが提供するキーバリュー型のNoSQLデータベース
  • SQLを使わずにデータの操作を行うことができる
  • プライマリキーの設定は、パーティションキーのみとパーティションキーとソートキーを使う方法の2種類を選択することができる
  • 基本的にはソートキー以外でしかデータのソート絞り込みはできない
  • ソートキー以外でデータのソートを行いたい場合は、セカンダリインデックスを使用する
  • GSI(グローバルセカンダリインデックス)を使うと、デフォルトで設定したものとは異なるパーティションキーとソートキーを設定することができる
  • LSI(ローカルセカンダリインデックス)を使うと、ソートキーだけデフォルトで設定したものとは別のキーを設定することができる

基本レベルのことしか書けませんでしたが、少しはDynamoDB分かった気がします。

→個人的には、GSI・LSIあたりが理解するの大変でした。。。

色々調べてコードとかも書いてやっとちょっと理解できたかなーという感じです。

RDBしか触ったことないけど、DynamoDB触ることになっちゃったみたいな人の役に立てれば幸いです。

おまけ

強い整合性と結果整合性の違い

  • 強い整合性・・・変更が完了するまで他の人は古いデータを参照できない
  • 結果整合性・・・変更が完了していない状態でも他の人は古いデータを参照できる

強い整合性は「見ている情報は常に最新であることを担保できている状態」で、結果整合性は「見ているデータは古い可能性がある」という感じでしょうか。

https://www.guri2o1667.work/entry/2020/10/26/%E3%80%90AWS%E3%80%91%E7%B5%90%E6%9E%9C%E6%95%B4%E5%90%88%E6%80%A7%E3%81%A8%E5%BC%B7%E6%95%B4%E5%90%88%E6%80%A7%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6