

# DynamoDB でのデバイスステータス更新のモニタリング
<a name="data-modeling-device-status"></a>

このユースケースでは、DynamoDB を使用して、DynamoDB 内でデバイスのステータスの更新 (またはデバイスのステータスの変更) をモニタリングする方法について説明しています。

## ユースケース
<a name="data-modeling-schema-device-status-use-case"></a>

IoT のユースケース (スマートファクトリーなど) では、多くのデバイスをオペレーターがモニタリングする必要があり、オペレーターはステータスやログをモニタリングシステムに定期的に送信します。デバイスに問題が発生すると、デバイスのステータスが [正常] から [警告] に変わります。デバイスの異常な動作の重大度やタイプによって、さまざまなログレベルまたはステータスがあります。その後、システムはデバイスをチェックするオペレーターを割り当て、オペレーターは必要に応じて問題を上司にエスカレーションします。

このシステムの典型的なアクセスパターンには次のものがあります。
+ デバイスのログエントリを作成する
+ 特定のデバイスステータスのすべてのログを取得し、最新のログを最初に表示する
+ 2 つの日付間の特定のオペレーターのすべてのログを取得する
+ 特定のスーパーバイザーのエスカレーションされたログをすべて取得する
+ 特定のスーパーバイザーの特定のデバイスステータスに関するすべてのエスカレーションログを取得
+ 特定の日付における特定のスーパーバイザーの特定のデバイスステータスを含むすべてのエスカレーションされたログを取得する

## エンティティ関係図
<a name="data-modeling-schema-device-status-erd"></a>

これは、デバイスステータスの更新をモニタリングするために使用するエンティティ関係図 (ERD) です。

![\[デバイスステータスの更新を示す ERD。エンティティ (デバイスとオペレーター) を示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-1-ERD.jpg)


## アクセスパターン
<a name="data-modeling-schema-device-status-access-patterns"></a>

デバイスのステータス更新をモニタリングする方法について説明します。

1. `createLogEntryForSpecificDevice`

1. `getLogsForSpecificDevice`

1. `getWarningLogsForSpecificDevice`

1. `getLogsForOperatorBetweenTwoDates`

1. `getEscalatedLogsForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisorForDate`

## スキーマ設計の進化
<a name="data-modeling-schema-device-status-design-evolution"></a>

**ステップ 1: アクセスパターン 1 (`createLogEntryForSpecificDevice`) と 2 (`getLogsForSpecificDevice`) に対処する**

デバイス追跡システムのスケーリングの単位は、個々のデバイスです。このシステムでは、`deviceID` はデバイスを一意に識別します。これにより、`deviceID` がパーティションキーの適切な候補となります。各デバイスは定期的に (例えば 5 分おきに) 情報を追跡システムに送信します。この順序によって、日付が論理的なソート基準となり、したがってソートキーになります。この場合のサンプルデータは次のようになります。

![\[複数のデバイスのステータスを保存するテーブル。DeviceID はプライマリキー、ステータス更新日はソートキーです。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-2-Step1.png)


特定のデバイスのログエントリを取得するには、パーティションキー `DeviceID="d#12345"` を使用して[クエリ](Query.md)オペレーションを実行します。

**ステップ 2: アクセスパターン 3 (`getWarningLogsForSpecificDevice`) に対処する**

`State` は非キー属性であるため、現在のスキーマでアクセスパターン 3 に対処するには[フィルター式](Query.FilterExpression.md)が必要になります。DynamoDB では、フィルター式はキー条件式を使用してデータを読み取った後に適用されます。例えば、`d#12345` の警告ログを取得する場合、パーティションキー `DeviceID="d#12345"` を使用したクエリオペレーションは、上記のテーブルから 4 つの項目を読み取り、*警告*ステータスなしで 1 つの項目をフィルターで除外します。このアプローチは大規模な場合は効率的ではありません。フィルター式は、除外される項目の割合が低い場合や、クエリの実行頻度が低い場合に、クエリ対象の項目を除外するのに適した方法です。ただし、テーブルから多くの項目が取得され、その大半の項目がフィルターで除外される場合は、より効率的に実行されるようにテーブル設計を進化させ続けることができます。

[複合ソートキー](data-modeling-blocks.md#data-modeling-blocks-composite)を使用して、このアクセスパターンを処理する方法を変更してみましょう。ソートキーを `State#Date` に変更したサンプルデータを [DeviceStateLog\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_3.json) からインポートできます。このソートキーは、属性 `State`、`#`、および `Date` から構成されます。この例では、`#` は区切り文字として使用されています。これで、データは次のようになります。

![\[複合ソートキー State#Date を使用して取得したデバイス d#12345 のステータス更新データ。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-3-Step2.png)


デバイスの警告ログのみを取得する場合は、このスキーマの方がクエリの対象が絞り込まれます。クエリのキー条件にはパーティションキー `DeviceID="d#12345"` とソートキー `State#Date begins_with “WARNING”` が使用されます。このクエリは、警告ステータスの関連する 3 つの項目のみを読み取ります。

**ステップ 3: アクセスパターン 4 (`getLogsForOperatorBetweenTwoDates`) に対処する**

`Operator` 属性がサンプルデータとともに `DeviceStateLog` テーブルに追加された [DeviceStateLog\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_4.json)D をインポートできます。

![\[特定の日付間におけるオペレーターのログを取得するための Operator 属性を備えた DeviceStateLog テーブル設計。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-4-Step3.png)


`Operator` は現在パーティションキーではないため、`OperatorID` に基づいてこのテーブルのキーと値を直接検索する方法はありません。`OperatorID` にグローバルセカンダリインデックスを使用して新しい[項目コレクション](WorkingWithItemCollections.md)を作成する必要があります。アクセスパターンでは日付に基づく検索が必要なため、日付が[グローバルセカンダリインデックス (GSI)](GSI.md) のソートキー属性になります。GSI は現在次のようになっています。

![\[特定の演算子のログを取得するために OperatorID と Date をパーティションキーおよびソートキーとして使用する GSI 設定。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-5-Step3.png)


アクセスパターン 4 (`getLogsForOperatorBetweenTwoDates`) の場合、`2020-04-11T05:58:00` と `2020-04-24T14:50:00` の間のパーティションキー `OperatorID=Liz` とソートキー `Date` を使用してこの GSI をクエリできます。

![\[OperatorID と Date を使用して GSI にクエリを実行し、2 つの日付間における演算子のログを取得します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-6-GSI1_1.png)


**ステップ 4: アクセスパターン 5 (`getEscalatedLogsForSupervisor`)、6 (`getEscalatedLogsWithSpecificStatusForSupervisor`)、および 7 (`getEscalatedLogsWithSpecificStatusForSupervisorForDate`) に対処する**

[スパースインデックス](data-modeling-blocks.md#data-modeling-blocks-sparse-index)を使用して、これらのアクセスパターンに対処します。

グローバルセカンダリインデックスはデフォルトではスパースであるため、インデックスのプライマリキー属性を含むベーステーブルの項目だけが実際にインデックスに表示されます。これは、モデル化するアクセスパターンに関係のない項目を除外するもう 1 つの方法です。

`EscalatedTo` 属性がサンプルデータとともに `DeviceStateLog` テーブルに追加された [DeviceStateLog\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_6.json) をインポートできます。前述のように、すべてのログがスーパーバイザーにエスカレーションされるわけではありません。

![\[スーパーバイザーにエスカレーションされたすべてのログを取得するための EscalatedTo 属性を備えた GSI 設計。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-7-Step4.png)


これで、`EscalatedTo` がパーティションキー、`State#Date` がソートキーである新しい GSI を作成できるようになりました。`EscalatedTo` 属性と `State#Date` 属性の両方を持つ項目のみがインデックスに表示されることに注意してください。

![\[GSI 設計で EscalatedTo 属性と State#Date 属性を備えたすべての項目を取得する GSI 設計。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-8-Step4.png)


その他のアクセスパターンは、以下のようにまとめられています。

    アクセスパターン 5 (GetEscalatedLogsForSupervisor) では、エスカレーション GSI に対してパーティションキー EscalatedTo="Sara" でクエリを実行できます。   アクセスパターン 6 (getEscalatedLogsWithSpecificStatusForSupervisor) の場合、パーティションキー EscalatedTo="Sara" およびソートキー State\$1Date begins\$1with "WARNING" を使用してエスカレーション GSI に対してクエリを実行できます。   アクセスパターン 7 (getEscalatedLogsWithSpecificStatusForSupervisorForDate) の場合、パーティションキー EscalatedTo="Sara" およびソートキー State\$1Date begins\$1with "WARNING4\$12020-04-27" を使用してエスカレーション GSI に対してクエリを実行できます。    

すべてのアクセスパターンと各アクセスパターンにスキーマ設計で対処する方法を次の表にまとめています。


| アクセスパターン | ベーステーブル/GSI/LSI | Operation | パーティションキー値 | ソートキー値 | その他の条件/フィルター | 
| --- | --- | --- | --- | --- | --- | 
| createLogEntryForSpecificDevice | ベーステーブル | PutItem | DeviceID=deviceId | State\$1Date=state\$1date |  | 
| getLogsForSpecificDevice | ベーステーブル | クエリ | DeviceID=deviceId | State\$1Date begins\$1with "state1\$1" | ScanIndexForward = False | 
| getWarningLogsForSpecificDevice | ベーステーブル | クエリ | DeviceID=deviceId | State\$1Date begins\$1with "WARNING" |  | 
| getLogsForOperatorBetweenTwoDates | GSI-1 | クエリ | Operator=operatorName | Date between date1 and date2 |  | 
| getEscalatedLogsForSupervisor | GSI-2 | クエリ | EscalatedTo=supervisorName |  |  | 
| getEscalatedLogsWithSpecificStatusForSupervisor | GSI-2 | クエリ | EscalatedTo=supervisorName | State\$1Date begins\$1with "state1\$1" |  | 
| getEscalatedLogsWithSpecificStatusForSupervisorForDate | GSI-2 | クエリ | EscalatedTo=supervisorName | State\$1Date begins\$1with "state1\$1date1" |  | 

## 最終スキーマ
<a name="data-modeling-schema-device-status-final-schema"></a>

最終的なスキーマ設計は次のとおりです。このスキーマ設計を JSON ファイルとしてダウンロードするには、GitHub の [DynamoDB の例](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples)を参照してください。

**ベーステーブル**

![\[デバイス ID、状態、日付などのデバイスステータスメタデータを使用したベーステーブル設計。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-9-Table.png)


**GSI-1**

![\[GSI-1 設計。プライマリキーと属性 (DeviceID、State#Date、State) を示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-10-GSI1.png)


**GSI-2**

![\[GSI-2 設計。プライマリキーと属性 (DeviceID、Operator、Date、State) を示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-11-GSI2.png)


## このスキーマ設計での NoSQL Workbench の使用
<a name="data-modeling-schema-device-status-nosql"></a>

この最終スキーマを、DynamoDB のデータモデリング、データ視覚化、クエリ開発機能を提供するビジュアルツールである [NoSQL Workbench](workbench.md) にインポートして、新しいプロジェクトを詳しく調べたり編集したりできます。使用を開始するには、次の手順に従います。

1. NoSQL Workbench をダウンロードします。詳細については、「[DynamoDB 用の NoSQL Workbench のダウンロード](workbench.settingup.md)」を参照してください。

1. 上記の JSON スキーマファイルをダウンロードします。このファイルは既に NoSQL Workbench モデル形式になっています。

1. JSON スキーマファイルを NoSQL Workbench にインポートします。詳細については、「[既存のデータモデルのインポート](workbench.Modeler.ImportExisting.md)」を参照してください。

1. NOSQL Workbench にインポートしたら、データモデルを編集できます。詳細については、「[既存のデータモデルの編集](workbench.Modeler.Edit.md)」を参照してください。