この記事は個人ブログと同じ内容です
はじめに
こんにちは、back checkでSWEとして活動しているぐっきー(@Area029S)です。 さて、最近 back check のプロダクトで一部 DynamoDB を導入しました。 私自身DynamoDBを触るのが初めてであり、理解を定着させるためにドキュメントや書籍でキャッチアップした内容をもとに DynamoDB で登場する基本的な概念についてまとめます。
基本概念
Table
RDBのテーブルのようなもの。概念的に一緒に属しているレコードをグループ化しておく場所。スキーマレスであるため、複数種類のエンティティを1つのテーブルに格納することが可能です。
RDBのテーブルと異なる部分
- 設計方法
- RDBのテーブルには単一のエンティティのみを含める設計が多いが、DynamoDBだと複数のエンティティを含めることが多い。
- これはsingle-table designと呼ばれ、複雑なjoinを避け、以下の恩恵をもたらします。
- テーブル数をなるべく少なくすることで、スケーラビリティが向上したり、運用のオーバーヘッドを低く抑えられることなどが見込めます。
- スキーマレス
Item(項目)
DynamoDBのテーブルに格納される1つのレコード。
RDBのrowに相当する。
Attributes(属性)
DynamoDBのItemはAttributesで構成される。 Attributesとは、要素の情報を保持する型付きのデータ値。
AttributesはRDBのレコードのカラムに似ているが、RDBのようにすべてのアイテムに属性が必要というわけではない。
DynamoDBにItemを書き込むと、各Attributesには特定の型が付与されます。
Amazon DynamoDB でサポートされるデータ型と命名規則
DynamoDBのデータ型 | カテゴリ |
---|---|
string | Scalars |
number | Scalars |
binary | Scalars |
boolean | Scalars |
null | Scalars |
list | Complex |
map | Complex |
string set | Sets |
number set | Sets |
binary set | Sets |
Scalersに分類されるデータ型は、プリミティブで単純な値とされる。
Item: { username: '山田太郎', // string ...etc, }
Complexに分類されるデータ型は、柔軟なAttributesであり、任意の入れ子構造を持つグループを表現する。
Item: { work: { "occupation": "ソフトウェアエンジニア", "company": "株式会社〇〇" }, // map ...etc, }
Complexに分類されるデータ型は、同じデータ型で構成されます。 文字列だけ、数値だけなどで構成されたリストを使いたいようなケースに有用です。 string型を指定したListなどとして商品タグを作ったりする際に活用できます。
Item: { "productID": "123", "productName": "スニーカー", "categories": { "SS": ["メンズ", "靴", "スポーツ"], // string set } ...etc, }
Primary keys(主キー)
Primary keyはテーブル作成の際に必ず宣言する必要があります。 Primary keysは1つの値からなるもの(パーティションキー)と、2つの値からなる複合的なもの(複合プライマリキー: パーティションキーとソートキーの組み合わせ)があります。 これらはテーブル内のItemごとに一意のものとする必要があります。
パーティションキー単体で管理する場合は、1対1の操作で個々のItemを操作する場合に有効です。 複合プライマリキーを活用することで同じパーティションキーを持つ全てのアイテムを取得したり、ソートキーに条件を指定するようなクエリを使用することが可能です。複合プライマリキーで管理すれば、Item間のリレーションを処理したり、複数のItemの一括取得が可能になります。
Primary keyの選択と設計は、データアクセスのほとんどをPrimary keyで行うことになるため、DynamoDBのデータモデリングで最も重要な要素と言われます。
パーティションキー(PK)
1つのAttributesから構成されるキー(文字列)です。
ソートキー(SK)
1つ以上のAttributesから構成されるキー(文字列)です。
Secondary indexes
DynamoDBのアクセスパターンはPrimary keyで決まるが、1つのアクセスパターンには対応できても、2つ目のアクセスパターンには対応できない場合があります。 これに対応するためにSecondary indexという概念が存在します。 Primary keyに並び、DynamoDBのデータモデリングで重要な要素と言われています。
ただしSecondary indexはソートキーで代替が容易にできる場合にはなるべくソートキーを利用するように寄せた方がよい。 その主な理由としては以下となります。 - テーブル毎にGlobal secondary indexは20個、Local secondary indexは5個までしか設定できないため、多用するうちに使用可能上限に達してしまう可能性がある。 - Global secondary index, Local secondary indexの設定は一意な値でなくても設定が可能です。そのためプライマリーキーを利用した参照と違い、結果の一意性を担保することができない。
そこで2つ目以降のアクセスパターンに対応する代替の手段として、ソートキーに複数の変数を組み込む方法があります。
// ソートキーに複数の変数を持たせるサンプル // User Entity attributes: { PK: { default: (data) => `userId#${data.userId}`, partitionKey, type: 'string', }, SK: { default: (data) => `departmentRole#${data.department}#${data.role}` sortKey, type: 'string', }, ...etc, }
この例では、ソートキー departmentRole は2つの変数、つまり部署(department)と役職(role)を含んでいます。これらの変数は # で連結されており、このようにソートキーを設計することで2つ以上のアクセスパターンを表現することが可能になります。
PK | SK | SK | Attribute |
---|---|---|---|
userId | department | role | etc... |
例えば、特定の部署のすべてのユーザーをクエリしたい場合、または特定の部署の特定の役職を持つユーザーをクエリしたい場合、といった異なるアクセスパターンに対応することができます。
Secondary index の種類
- Local secondary indexes
- Global secondary indexes
Local secondary indexes
Local secondary indexはテーブルのPrimary keyと同じパーティションキーを使用するが、異なるソートキーを使用します。 これはパーティションキーに対してLocal secondary indexを用いてソートキーとは別のパターンのフィルタリングをしたいような場合に活用できます。
Global secondary indexes
Global secondary indexはパーティションキーとソートキーにテーブル内の自由なAttributeを選ぶことができます。
注意事項として、Global secondary indexを利用する場合、内部的にはコアテーブルとは別でGlobal secondary index 用のテーブルが用意されます。データはコアテーブルからGlobal secondary indexに非同期(通常数秒以内)で複製されるため、Global secondary indexで返されるデータは、タイミングによってはメインテーブルの最新の書き込みを反映していない可能性があります。しかし、これは結果整合性と呼ばれるモデルであり、用途に応じて充分許容可能な一貫性があるとも言えます。
※ 記事内ででてくるソースコードはdynamodbtoolboxの表記に沿ってイメージを伝えるために作成したものであり、実際に動作を保証するものではありません。
おわりに
以上、簡単なDynamoDBの基本概念まとめでした。 新規でDynamoDBをキャッチアップをする人の理解の促進に繋がればと思います。
参考資料
The DynamoDB Book DynamoDB 用の NoSQL Amazon DynamoDB でサポートされるデータ型と命名規則 DynamoDBテーブルのSet型でタグ的な項目を管理する Amazon DynamoDB のコアコンポーネント Amazon DynamoDB テーブルに適切なプライマリキーを選択するにはどうすればよいですか? DynamoDBのキー・インデックスについてまとめてみた