DynamoDBを試してみた

# 背景・目的
- 先日、[Lambdaを定期実行する](https://qiita.com/zumastee/items/8882c45fc199c7ea4138)で作成したLambdaで、Qiitaの記事をデータストアに保存してみる。
- データストアには、今まであまり触ってこなかったDynamoDBを使用してみる。
- 本ページでは、まずはDynamoDBでテーブル作成、簡単なサンプルデータを登録するところまでをスコープとし、Lambdaを利用してのデータ登録等は次回以降に試す。

# 内容
## DynamoDBの概要
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html

### DynamoDB（以降、DDBという。）とは

- フルマネージドNoSQLデータベースサービス
- 高速、予測可能なパフォーマンスとシームレスにスケールを提供する。
- ディストリビューションデータベースの運用とスケーリングに伴う管理作業をまかせることができる。
- ハードウェアのプロビジョニング、設定と構成、レプリケーション、ソフトウェアパッチ適用、クラスタースケーリングなどを自分で行う必要はない。
- 保管時の暗号化を提供し、機密データの保護に伴う複雑な運用の負担を取り除く。

### 高い可用性と耐久性
- 一貫性のある高速パフォーマンスを維持しながら、スループットとストレージの要件を処理できるように、テーブルのデータとトラフィックが十分な数のサーバに自動的に分散される。
- 全てのデータをSSDに保存し、リージョン内の複数AZ間で自動でレプリケートするため、高い可用性とデータ堅牢性が実現する。
- グローバルテーブルにより、DDB
- テーブルをAWSリージョン間で同期可能。

## 仕組み
### コアコンポーネント
- テーブル、項目、属性を指す。
- テーブルは項目の集合、各項目は属性の集合。
- PKを使用してテーブルの各項目を一意に識別し、セカンダリインデックスを使用してクエリの柔軟性を高める。

### プライマリーキー
- テーブル作成時には、テーブル名とPKを指定する必要がある。
- パーティションキー
    - DDBはパーティションキーを内部ハッシュ関数への入力として使用する。ハッシュ関数からの出力により、項目が保存されるパーティションが決まる。
- パーティションキーとソートキー
    - 複合プライマリーキー
    - 2つの属性で決まり、1つめがパーティションキー。2つめがソートキー
    - 2つめのソートキーでソートされて保存される。

### セカンダリーインデックス
- 指定することで、プライマリーキー以外の検索に柔軟性が出る。
- ２種類ある
    - グローバルセカンダリーインデックス（以降、GSIという。）
        - パーティションキーおよびソートキーを持つインデックス。
        - テーブルのものとは異なる。
    - ローカルセカンダリーインデックス（以降、LSIという。）
        - パーティションキーはテーブルのものと同じ。ソートキーが異なるインデックス。
- 各テーブルには、２０個のGSIと5個のLSIのクォータがある。

### DynamoDB Streams
- DDBテーブルの変更イベントをキャプチャする。
- ほぼリアルで、イベントの発生順にストリームに表示される。
- テーブルでストリームを有効にすると、DDB Streamsは以下のイベントごとにストリーミングレコードを書き込む
    - 新しい項目がテーブルに追加された場合、全てをキャプチャ
    - 項目が更新された場合、更新された項目の更新前後のキャプチャ
    - 削除された場合、削除前の項目全体のキャプチャ

- 24Hの有効期限を持つ。
- DDB StreamとLambdaで、トリガーを作成できる。

## 実践
[DynamoDBの使用開始](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)を参考に始める。ただし、テーブル名や項目は適宜変更する。

### ステップ 1: テーブルを作成する
- qiita_user_articlesというテーブル名で、以下の項目を作成する。

| 項目名 | キー | タイプ| 
|:--- | :---- | :---- | 
| user_id | パーティションキー| 文字列 | 
| article_id | ソートキー | 文字列 |


1.マネコンのDynamoDBコンソール＞ダッシュボード＞右側のテーブルの作成をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/af388abe-963e-9c3d-20a1-5934aa502921.png)

2.テーブル名と、パーティションキーを予め決めたものを入力し、設定は一旦デフォルトのままでテーブルの作成をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/75e2952a-eacc-9cac-d2d1-2fa9412c3b5c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d066f921-6d58-cff4-ae11-2a863c307a8a.png)

3.しばらくするとActivateされ、以下のように確認ができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/4e236078-23c3-90bf-1484-25e5f351acce.png)

### ステップ 2: コンソールまたは AWS CLI を使用して、テーブルにデータを書き込む
- 作成したテーブルにデータを書き込む。
1.テーブルの一覧でテーブル名をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e1f426ed-3000-b630-b3c2-033e95f39a3d.png)

2.画面右上の「テーブルアイテムの探索」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fcf1fa7b-480d-4748-d360-69acf6872113.png)

3.画面右上の「項目の作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/cccb1483-555b-1aef-2110-3292b19bfe17.png)

4.「新しい属性の追加」でタイプを選ぶと新しい項目が追加される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b6a81836-6335-7190-b041-3f6c15fae63a.png)

5.以下の様に作成し、「項目を作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f59a4f79-7752-89b4-3e39-95a0ae14cb5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0e4fd65c-28de-451f-64e3-b8aae39128af.png)

### ステップ 3: テーブルからデータを読み込む
- スキャンとクエリがある。スキャンを実行してみる。
1.フィルタの属性に「user_id」、値に「test」を入力し、「実行する」をクリックすると、以下のように表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ca6b918b-4e57-67d1-79b7-0d30040ebb4b.png)

2.フィルタの属性に「user_id」、値に「**test2**」を入力し、「実行する」をクリックすると、以下のように表示される。（結果は返されない。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2a13e10e-6498-6c21-984c-f266285a56f4.png)

### ステップ 4: テーブルのデータを更新する
- 更新をしてみる。

1.検索結果のパーティションキーがリンクになっているのでクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c1391219-87a1-8e07-77e5-9f4047f43c48.png)

2.titleの値を「updated test title」に変更し「変更を保存」をクリックすると、変更されたことが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/718be5e3-b7c3-6df1-82a3-9317c6abc838.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fe5f5a74-f20a-b1f3-2a8b-ddce6c393a28.png)

### ステップ 5: テーブルのデータをクエリする
- ステップ3とほぼ同様なので、省略する。

### ステップ 6: グローバルセカンダリインデックスを作成する
1.テーブルを選び、「インデックス」タブをクリック後、画面右上の「インデックスの作成」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2e0475e9-75db-182f-c6af-cda80d043cd7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fce10169-00c1-6235-dc38-df760ef7f18c.png)

2.インデックスの詳細でパーティションキー「title」を指定し、その他は変更せずに「インデックスの作成」をクリックする。
キャプチャなし。


3.しばらくするとActiveになる。最大5分くらいかかるらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/829f4328-a9aa-8e71-2d6e-9a89200cd3e5.png)


### ステップ 7: グローバルセカンダリインデックスをクエリする
- 作成したGSIでクエリしてみる。

1.アイテムのスキャン/クエリでテーブルまたはインデックスに先程作成した「title-index」が表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fa7372a8-5fdd-7c73-124d-d6cf1bf8a120.png)

2.title-indexに「updated test title」を指定し「実行する」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/71fa7c7f-edc8-57f7-00a4-94b156728ce1.png)

3.以下は、title-indexに「deleted test title」を指定し結果が帰らなかった例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/000d859b-5296-d318-70b5-097c9fb66100.png)

# 考察
- マネコン上で、テーブルの作成から、データ操作まで簡単にできる。
- DDBのキャパシティーユニットなどは、今後確認する予定。

# 参考
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html

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