【AWS】用語を整理しながら学ぶAWS Amazon DynamoDB

## はじめに

この記事では AWSが提供するAmazon DynamoDB（以下、DynamoDB）を学習していく記事です。主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

## Amazon DynamoDBとは

DynamoDBはAWSが提供するフルマネージドでサーバーレスのkey-value型NoSQLデータベースです。AWSの公式サイトには下記のように表現されています。

> 1 桁ミリ秒単位で規模に応じたパフォーマンスを実現する高速で柔軟な NoSQL データベースサービス

> 開発者は Amazon DynamoDB を使用して、小規模から始めてグローバルにスケールできる最新のサーバーレスアプリケーションを構築できます。Amazon DynamoDB は、自動水平スケーリングにより、事実上あらゆるサイズのテーブルをサポートするようにスケールされます。

> 無限のスケーラビリティを備えたサーバーレスのパフォーマンス

[Amazon DynamoDB の特徴](https://aws.amazon.com/jp/dynamodb/features/)

なにやらすごいデータベースであることは分かりましたが、何がどうすごいのかナニモワカラナイです。基本から見ていきましょう。

## そもそもNoSQLとは

DynamoDBを理解するためにはまずはNoSQLを理解しなければいけません。
実はAWSのサイトを検索するとNoSQLについても解説されています。

> NoSQL は、拡張が容易な柔軟なスキーマにデータを保存するデータベーステクノロジーです。何十年もの間、アプリケーション開発における主なデータモデルは、行と列で構成されるテーブルにデータを格納するリレーショナルデータモデルでした。これらのリレーショナルテーブルの作成と編集には、構造化クエリ言語 (SQL) が使用されていました。他の柔軟なデータモデルが広く採用され始めたのは、2000 年代半ばから後半にかけてです。

[NoSQL とは](https://aws.amazon.com/jp/nosql/)

従来までデータベースというとリレーショナルデータベースでした。つまりは

「クエリ言語であるSQLを書いて、データベースクライアントからデータの取り出しを実行、取り出したデータをアプリケーションに入力する」という形でした。
現在においては「アプリケーションに利用するデータベースというとリレーショナルデータベースだけでなく、非リレーショナルなデータベースも存在している」ということです。

なお、AWSで提供されているリレーショナルデータベース、Amazon RDSについては解説していますので、気になる方は読んでいただけますと幸いです。

[【AWS】用語を整理しながら学ぶAWS Amazon RDS](https://qiita.com/ymd65536/items/9985d23514b69b380d83)

## NoSQLをなぜ使うのか

言葉を選ばずに説明するとスキーマレスであるということです。AWSのサイトには下記のような記述があります。

> これらの新しいクラスのデータベースとデータモデルを区別し、分類するために NoSQL という用語が登場しました。NoSQL は、SQL や非 SQL だけの略ではありません。多くの場合、NoSQL という用語は非リレーショナルと同じ意味です。

柔軟性の高いデータをリレーショナルデータベースで利用するとき、非常に難しい状況に陥る場合があります。たとえば、新しい列（属性）のデータを扱うときです。

リレーショナルデータベースの場合はどのようなものを受け入れるかどうかに関係なく、新しいスキーマを定義する必要があります。

ここで具体例を見ていきましょう。
たとえば、衣服の情報と本の情報を同時に持ったデータベースがある時どのようなスキーマを定義するでしょうか。

下記の表はイメージなので実装が悪いなどの所感はあると思いますが、この際それは無視してください。

|商品名|単価|サイズ|ページ数|
|:---|:---|:---|:---|
|衣服|3000|L|NULL|
|本|1500|NULL|300ページ|

上記のような表を見ていただくとわかるとおり、商品によってどのような情報を持つかは変わってきます。衣服にはページ数はありませんし、本には服のようなサイズはありません。あるとしても「大判」や「単行本」くらいなものですが、それは衣服のサイズではありません。

さらに上記の表に対して「著者」というカラムをつけてみたらどうなるでしょうか。

|商品名|単価|サイズ|ページ数|著者|
|:---|:---|:---|:---|:---|
|衣服|3000|L|NULL|NULL|
|本|1500|NULL|300ページ|Kento.Yamada|

衣服には著者はいないと思います。もうお気づきかもしれませんが、どのようなデータが入ってきても同じカラムを保証するのがリレーショナルデータベースの良いところであり、悪いところでもあります。

そこでデータ毎にカラムを用意してそのデータを完全に保存するためのスキーマを提供してあげます。NoSQLの分野ではデータにある特徴を「属性」、データ自体を「アイテム」などと呼ぶことがあります。

データに合わせたスキーマを用意することで不要なスキーマを持つことなく、データを格納できます。

## データを取り出す時はどうするの？

ここまでくるとお気づきかもしれません。リレーショナルデータベースではクエリ言語を使うことでデータを取り出すことができました。
では、NoSQLでデータを取り出すときはどのようにすれば良いのでしょうか。
NoSQLではアプケーションやAPIを介してデータを取り出すようになっています。

なお、DynamoDBには専用のクエリ言語が用意されていますが、それはのちほど解説します。

## NoSQLの種類

そんなNoSQLですが、さまざまな種類があります。
下記の5つの中でDynamoDBはKey-value データベースとなります。

- Key-value データベース
- ドキュメントデータベース
- グラフデータベース
- インメモリデータベース
- 検索エンジンデータベース 

### Key-valueとは

特定の文字列に任意の文字列を関連づけた形です。
おそらく、jsonをご存知の方はイメージしやすいでしょう。具体的には以下の形式です。

```json
{
    "key":"value"
}
```

リレーショナルデータベースと関連付けて考えるとカラムが`key`と同じ意味なり、`value`がそのカラムの値となるイメージです。

## DynamoDBの特徴

DynamoDBが保存できるデータを見ていったところで具体的にはどのようなことができるのか機能面にフォーカスして見ましょう。

### フルマネージド

まずは、フルマネージドであるというところです。つまりは、本当に管理が不要のデータベースということになります。

そもそもデータベースを構築する上ではサーバとそれらを束ねるクラスターの管理が必要となります。それらの構築と管理が不要となるところは大きなポイントです。

### メンテナンスウィンドウがない

構築と管理が不要な上にメンテナンスが存在しません。クラウドでもオンプレミスでも管理が必要となってくるとなると停止時間が発生するものですが、DynamoDBに関しては存在しません。

### 最大 99.999% の可用性

どんなサービスでも可用性は存在しますが、DynamoDBに関してはファイブナインの可用性があります。つまり、ほとんどの場合で動いているということです。

### サーバレス

驚くべきことにファイブナインの可用性を持ちながら、サーバレスであるということです。
つまりはインスタンスが見えないということになります。
ただし、インスタンスが見えないということは稼働状況を把握できないということになりますから
手放しで喜べるものでもありません。

### 無限のスケーラビリティ

データベースは使っていくうちにデータが累積していき、事業規模に応じてCPUも足りなくなることがありますが、DynamoDBに関しては多くの場合、気にする必要がありません。

### 1 桁ミリ秒という一貫したパフォーマンス

データベースというコンポーネントはデータを保存しているだけあってレイテンシがアプリケーションのパフォーマンスに直結します。
もちろん、アプリケーションが遅い場合はいろんな原因が考えられますが、データベースのパフォーマンスが落ちたことによって発生するレイテンシもあります。

DynamoDBに関してはミリ秒単位の速さでデータをやり取りし、一貫したパフォーマンスを発揮します。

### グローバルテーブル

ファイブナインの可用性を発揮するため、複数リージョンに渡ってデータをレプリケーションできます。つまりはコピーを他のリージョンに持たせることができるので高可用でデータベースを利用できます。

### PartiQL

NoSQLではクエリ型言語をサポートしていませんが、DynamoDBではPartiQLというSQL互換のクエリ型言語をサポートしています。NoSQLだけども、SQLライクにデータを取り出せる仕組みがあるということです。

## 料金

とてもすごいデータベースであることが分かりましたが、いったいいくらで利用できるのでしょうか。料金はどのような機能を利用したのかによって大きく変わるのではっきりしたことは言えません。

ただし、まずはキャパシティモードとテーブルクラスについて理解しておけば、入門としては十分でしょう。

### オンデマンドキャパシティーモードとリザーブドキャパシティ

まずは、オンデマンドキャパシティモードは必要なときに必要な分だけ呼び出す場合の料金設定です。

ユニット単位で課金が発生します。ユニットは読み取りユニットのRCUと書き込みユニットのWCUがあります。

#### 補足：ユニットという単位

DynamoDBではRCUとWCUが登場していますが、GlueではDPU、AuroraではACUが登場します。
AWSではしばしばユニットという単位が登場してそれが料金に絡んでくることが多いです。

### Standard Infrequent Access (Standard-IA) テーブルクラス

DynamoDBの料金を抑える方法としてテーブルクラスの利用があります。通常のテーブルクラスでデータを保存するのではなく、アクセス頻度の低いデータはStandard-IAのテーブルに保存するとコストの最適化につながります。

データをどのように保存するのかという観点はAmazon S3のストレージクラスと似ているところがあります。

なお、[Amazon S3](https://qiita.com/ymd65536/items/14ba426bca4eae3dc249)については過去に紹介しています。

## おわり

今回はAWSが提供するつよつよNoSQLデータベースのDynamoDBを紹介しました。
いろんなメリットを書きましたが、実はNoSQLをうまく使ってデータを管理するというのはなかなか難しいものです。

理由は先にも述べたとおり、スキーマレスであることです。レコード単位でどんな属性を持っているのかが把握しにくくなります。
各レコードでどのようなデータを持っているかがわからないと取り出すのも一苦労です。

ですが、APIで取り出すことを前提に考えており、APIが扱うデータモデルがDynamoDBのデータベースモデルであれば、迷うことなくデータを取り出せると思います。

利用時はどのようなデータを持っているかの仕様書を書くか
もしくは、APIによって取り出すことを前提にして取り出すデータの詳細を意識させないなどの工夫が必要です。

別の機会にDynamoDBを試すハンズオンを書きたいと思います。