

# DynamoDB での項目と属性の操作
<a name="WorkingWithItems"></a>

Amazon DynamoDB では、*項目*は属性の集まりです。各属性には名前と値があります。属性値はスカラー型、セット型、ドキュメント型のいずれかです。詳細については、「[Amazon DynamoDB: 仕組み](HowItWorks.md)」を参照してください。

DynamoDB では、作成、読み込み、更新、および削除 (CRUD) の 4 つの基本的な操作機能を使用できます。これらの操作はすべてアトミックです。
+ `PutItem` — 項目を作成します。
+ `GetItem` — 項目を読み込みます。
+ `UpdateItem` — 項目を更新します。
+ `DeleteItem` — 項目を削除します。

これらの各オペレーションでは、作業対象の項目のプライマリキーを指定する必要があります。たとえば、`GetItem` を使用して項目を読み込むには、その項目のパーティションキーとソートキー (該当する場合) を指定する必要があります。

4 つの基本的な CRUD オペレーションに加えて、DynamoDB は以下も提供します。
+ `BatchGetItem` — 1 つ以上のテーブルから最大 100 個の項目を読み込みます。
+ `BatchWriteItem` — 1 つ以上のテーブルから最大 25 個の項目を作成または削除します。

これらのバッチ操作は、複数の CRUD オペレーションを単一のリクエストにまとめます。さらに、応答のレイテンシーを最小限に抑えるため、バッチオペレーションは項目を並列で読み書きします。

このセクションには、これらのオペレーションを使用する方法の説明、および、条件付き更新やアトミックカウンターなどの関連するトピックが含まれています。このセクションには、AWS SDK を使用するサンプルコードも含まれています。

**Topics**
+ [DynamoDB 項目のサイズと形式](CapacityUnitCalculations.md)
+ [項目の読み込み](#WorkingWithItems.ReadingData)
+ [項目を書き込みます](#WorkingWithItems.WritingData)
+ [戻り値](#WorkingWithItems.ReturnValues)
+ [バッチオペレーション](#WorkingWithItems.BatchOperations)
+ [アトミックカウンタ](#WorkingWithItems.AtomicCounters)
+ [条件付きの書き込み](#WorkingWithItems.ConditionalUpdate)
+ [DynamoDB での式の使用](Expressions.md)
+ [DynamoDB での Time to Live (TTL) の使用](TTL.md)
+ [DynamoDB のテーブルに対するクエリの実行](Query.md)
+ [DynamoDB でのテーブルのスキャン](Scan.md)
+ [PartiQL: Amazon DynamoDB 用の SQL 互換クエリ言語](ql-reference.md)
+ [項目の操作: Java](JavaDocumentAPIItemCRUD.md)
+ [項目の操作: .NET](LowLevelDotNetItemCRUD.md)

## 項目の読み込み
<a name="WorkingWithItems.ReadingData"></a>

DynamoDB テーブルから項目を読み込むには、`GetItem` オペレーションを使用します。必要な項目のプライマリキーと共にテーブルの名前を指定する必要があります。

**Example**  
次の AWS CLI の例は、`ProductCatalog` テーブルから項目を読み込む方法を示しています。  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}'
```

**注記**  
`GetItem` では、プライマリキーの一部だけではなく*全体*を指定する必要があります。たとえば、テーブルに複合プライマリキー (パーティションキーおよびソートキー) がある場合、パーティションキーおよびソートキーの値を指定する必要があります。

デフォルトでは、`GetItem` リクエストは結果的に整合性のある読み込みを行います。代わりに、`ConsistentRead` パラメータを使用して、強い整合性のある読み込みをリクエストできます。(これは、追加の読み込みキャパシティーユニットを消費しますが、項目の最新バージョンを返します)。

`GetItem` は、項目のすべての属性を返します。一部の属性のみが返されるように、*プロジェクション式*を使用できます。詳細については、「[DynamoDB でのプロジェクション式の使用](Expressions.ProjectionExpressions.md)」を参照してください。

`GetItem` で消費される読み込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを `TOTAL` に設定します。

**Example**  
次の AWS Command Line Interface (AWS CLI) の例は、オプションの `GetItem` パラメータを示しています。  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --consistent-read \
    --projection-expression "Description, Price, RelatedItems" \
    --return-consumed-capacity TOTAL
```

## 項目を書き込みます
<a name="WorkingWithItems.WritingData"></a>

DynamoDB テーブルの項目を作成、更新、または削除するには、次のオペレーションのいずれかを使用します。
+ `PutItem`
+ `UpdateItem`
+ `DeleteItem`

これらの各オペレーションで、プライマリキーの一部の属性ではなくすべての属性を指定する必要があります。たとえば、テーブルに複合プライマリキー (パーティションキーおよびソートキー) がある場合、パーティションキーおよびソートキーの値を提供する必要があります。

これらのオペレーションのいずれかで消費される書き込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを次のいずれかに設定します。
+ `TOTAL` — 消費された書き込み容量単位の総数を返します。
+ `INDEXES` — 消費された書き込み容量単位の総数とともに、テーブルおよびオペレーションに影響を受けたセカンダリインデックスの小計を返します。
+ `NONE` — 書き込み容量の詳細は返されません。(これがデフォルトです)

### PutItem
<a name="WorkingWithItems.WritingData.PutItem"></a>

`PutItem` は新しい項目を作成します。同じキーを持つ項目がテーブルにすでに存在する場合は、新しい項目に置き換えられます。

**Example**  
`Thread` テーブルに新しい項目を書き込みます。`Thread` のプライマリキーは、`ForumName` (パーティションキー) と `Subject` (ソートキー) で構成されます。  

```
aws dynamodb put-item \
    --table-name Thread \
    --item file://item.json
```
`--item` の引数は、ファイル `item.json` に保存されます。  

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"},
    "Message": {"S": "First post in this thread"},
    "LastPostedBy": {"S": "fred@example.com"},
    "LastPostDateTime": {"S": "201603190422"}
}
```

### UpdateItem
<a name="WorkingWithItems.WritingData.UpdateItem"></a>

指定されたキーを持つ項目が存在しない場合は、`UpdateItem` により新しい項目が作成されます。または、既存の項目の属性が変更されます。

*更新式*を使用して、変更する属性と新しい値を指定します。詳細については、「[DynamoDB での更新式の使用](Expressions.UpdateExpressions.md)」を参照してください。

更新式では、実際の値にプレースホルダーとして式の属性値を使用します。詳細については、「[DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)」を参照してください。

**Example**  
`Thread` 項目のさまざまな属性を変更します。オプションの `ReturnValues` パラメータは、更新後に表示されるように項目を表示します。詳細については、「[戻り値](#WorkingWithItems.ReturnValues)」を参照してください。  

```
aws dynamodb update-item \
    --table-name Thread \
    --key file://key.json \
    --update-expression "SET Answered = :zero, Replies = :zero, LastPostedBy = :lastpostedby" \
    --expression-attribute-values file://expression-attribute-values.json \
    --return-values ALL_NEW
```

`--key` の引数は、ファイル `key.json` に保存されます。

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"}
}
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":zero": {"N":"0"},
    ":lastpostedby": {"S":"barney@example.com"}
}
```

### DeleteItem
<a name="WorkingWithItems.WritingData.DeleteItem"></a>

`DeleteItem` は指定されたキーを持つ項目を削除します。

**Example**  
次の AWS CLI の例で、`Thread` 項目を削除する方法について説明します。  

```
aws dynamodb delete-item \
    --table-name Thread \
    --key file://key.json
```

## 戻り値
<a name="WorkingWithItems.ReturnValues"></a>

場合によっては、ある属性値を変更する前後にその属性値が表示されるように DynamoDB で返すこともできます。`PutItem`、`UpdateItem`、および `DeleteItem` オペレーションには、`ReturnValues` パラメータがあり、これを使用することで、属性の変更前後に、その属性値を返すことができます。

`ReturnValues` のデフォルトの値は `NONE` で、DynamoDB は変更された属性の情報を返しません。

以下は、DynamoDB API オペレーションごとに整理された `ReturnValues` のその他の有効な設定です。

### PutItem
<a name="WorkingWithItems.ReturnValues.PutItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目に上書きする場合、`ALL_OLD` は上書きの前に表示されたように、項目全体を返します。
  + 存在しない項目を書き込んだ場合は、`ALL_OLD` による影響はありません。

### UpdateItem
<a name="WorkingWithItems.ReturnValues.UpdateItem"></a>

`UpdateItem` の最も一般的な使用方法は、既存の項目の更新です。ただし、`UpdateItem` は実際には*アップサート*を実行します。つまり、項目が存在しない場合は、自動的に作成します。
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目を更新する場合、`ALL_OLD` は更新前に表示されたように、項目全体を返します。
  + 存在しない項目を更新 (アップサート) すると、`ALL_OLD` による影響はありません。
+ `ReturnValues`: `ALL_NEW`
  + 既存の項目を更新する場合、`ALL_NEW` は更新後に表示されるように、項目全体が返されます。
  + 存在しない項目を更新 (アップサート) すると、`ALL_NEW` は項目全体を返します。
+ `ReturnValues`: `UPDATED_OLD`
  + 既存の項目を更新した場合、`UPDATED_OLD` は、更新前に表示されたように、更新された属性だけを返します。
  + 存在しない項目を更新 (アップサート) すると、`UPDATED_OLD` による影響はありません。
+ `ReturnValues`: `UPDATED_NEW`
  + 既存の項目を更新した場合、`UPDATED_NEW` は、更新後に表示されるように、影響のある属性だけを返します。
  + 存在しない項目を更新 (アップサート) する場合、`UPDATED_NEW` は更新後に表示される、更新された属性だけを返します。

### DeleteItem
<a name="WorkingWithItems.ReturnValues.DeleteItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目を削除すると、`ALL_OLD` は削除の前に表示されたように、項目全体を返します。
  + 存在しない項目を削除すると、`ALL_OLD` はデータを返しません。

## バッチオペレーション
<a name="WorkingWithItems.BatchOperations"></a>

複数の項目の読み込みや書き込みを必要とするアプリケーションのために、DynamoDB は `BatchGetItem` および `BatchWriteItem` オペレーションを提供します。これらのオペレーションを使用すると、アプリケーションから DynamoDB へのネットワークラウンドトリップの数を減らすことができます。さらに、DynamoDB は個別の読み込みまたは書き込みオペレーションを並行して実行します。同時実行またはスレッディングの管理をする必要がないので、アプリケーションにはこの並列処理が役立ちます。

バッチオペレーションは、基本的に複数の読み込みまたは書き込みリクエストをまとめます。たとえば、`BatchGetItem` リクエストに 5 つの項目が含まれている場合、DynamoDB によって 5 回の `GetItem` オペレーションが実行されます。同様に、`BatchWriteItem` リクエストに 2 つの PUT リクエストと 4 つの DELETE リクエストが含まれている場合、DynamoDB によって 2 つの `PutItem` リクエストと 4 つの `DeleteItem` リクエストが実行されます。

一般的に、バッチの*すべて*のリクエストが失敗しない限り、バッチオペレーションは失敗しません。たとえば、`BatchGetItem` オペレーションを実行する際、バッチの個々の `GetItem` リクエストが失敗したとします。この場合、`BatchGetItem` は失敗した `GetItem` リクエストからキーとデータを返します。バッチのその他の `GetItem` リクエストは影響を受けません。

### BatchGetItem
<a name="WorkingWithItems.BatchOperations.BatchGetItem"></a>

1 回の `BatchGetItem` オペレーションには、最大 100 の個々の `GetItem` リクエストが含まれていて、最大 16 MB のデータを取得できます。さらに、`BatchGetItem` オペレーションで、複数のテーブルから項目を取得できます。

**Example**  
一部の属性のみが返されるようにプロジェクション式を使用して `Thread` テーブルから 2 つの項目を取得します。  

```
aws dynamodb batch-get-item \
    --request-items file://request-items.json
```
`--request-items` の引数は、ファイル `request-items.json` に保存されます。  

```
{
    "Thread": {
        "Keys": [
            {
                "ForumName":{"S": "Amazon DynamoDB"},
                "Subject":{"S": "DynamoDB Thread 1"}
            },
            {
                "ForumName":{"S": "Amazon S3"},
                "Subject":{"S": "S3 Thread 1"}
            }
        ],
        "ProjectionExpression":"ForumName, Subject, LastPostedDateTime, Replies"
    }
}
```

### BatchWriteItem
<a name="WorkingWithItems.BatchOperations.BatchWriteItem"></a>

`BatchWriteItem` オペレーションには最大 25 の個々の `PutItem` リクエストと `DeleteItem` リクエストを含むことができ、最大 16 MB のデータを書き込めます。(個々の項目の最大サイズは 400 KB です。) さらに、`BatchWriteItem` オペレーションで、複数のテーブルの項目を入力したり削除したりできます。

**注記**  
`BatchWriteItem` では `UpdateItem` リクエストはサポートされません。

**Example**  
`ProductCatalog` テーブルに 2 つの項目を書き込みます。  

```
aws dynamodb batch-write-item \
    --request-items file://request-items.json
```
`--request-items` の引数は、ファイル `request-items.json` に保存されます。  

```
{
    "ProductCatalog": [
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "601" },
                    "Description": { "S": "Snowboard" },
                    "QuantityOnHand": { "N": "5" },
                    "Price": { "N": "100" }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "602" },
                    "Description": { "S": "Snow shovel" }
                }
            }
        }
    ]
}
```

## アトミックカウンタ
<a name="WorkingWithItems.AtomicCounters"></a>

この `UpdateItem` オペレーションを使用して、*アトミックカウンター* (他の書き込みリクエストに干渉することなく無条件に増分される数値属性) を実装できます。（すべての書き込みリクエストは、受信された順に適用されます）。アトミックカウンターでは、更新はべき等ではありません。つまり、`UpdateItem` を呼び出すたびに数値はインクリメントまたはデクリメントされます。アトミックカウンタの更新に使用されるインクリメント値が正の場合、オーバーカウントが発生する可能性があります。インクリメント値が負の場合、アンダーカウントの原因となります。

ウェブサイトの訪問者数を追跡するためにアトミックカウンターを使用できます。この場合、アプリケーションでは、現在値に関係なく、数値はインクリメントされます。`UpdateItem` オペレーションが失敗した場合、アプリケーションはオペレーションを再試行します。これには、カウンターを 2 度更新する恐れがありますが、ウェブサイトの訪問者数のカウントに多少の誤差があっても許容できるでしょう。

アトミックカウンターはカウントの誤差が許容されない場合にはふさわしくありません (銀行業務用のアプリケーションなど)。この場合は、アトミックカウンターの代わりに条件付き更新を使用する方が安全です。

詳細については、「[数値属性の増減](Expressions.UpdateExpressions.md#Expressions.UpdateExpressions.SET.IncrementAndDecrement)」を参照してください。

**Example**  
次の AWS CLI の例では、商品の `Price` が 5 でインクリメントされます。この例では、カウンタが更新される前に項目が存在することがわかっていました。(`UpdateItem` は冪等性ではないので、`Price` はこのコードを実行するたびに増えていきます)。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": { "N": "601" }}' \
    --update-expression "SET Price = Price + :incr" \
    --expression-attribute-values '{":incr":{"N":"5"}}' \
    --return-values UPDATED_NEW
```

## 条件付きの書き込み
<a name="WorkingWithItems.ConditionalUpdate"></a>

デフォルトでは、DynamoDB 書き込みオペレーション (`PutItem`、`DeleteItem`) は*無条件*です。つまり、これらの各オペレーションでは、指定されたプライマリキーを持つ既存の項目が上書きされます。

DynamoDB はオプションでこれらのオペレーションの条件付き書き込みをサポートしています。条件付き書き込みが成功するのは、項目の属性が 1 つ以上の想定条件を満たす場合のみです。それ以外の場合は、エラーが返されます。

条件付き書き込みでは、その条件について項目の最新更新バージョンと照合します。なお、項目が以前に存在しなかった場合や、その項目に対して最後に成功した操作が削除であった場合、条件付き書き込みでは以前の項目は検出されません。

 条件付き書き込みは多くの状況で役立ちます。たとえば、同じプライマリキーを持つ既存の項目がない場合にのみ、`PutItem` オペレーションが成功するようにできます。または、属性の 1 つに特定の値がある場合に `UpdateItem` オペレーションが項目を変更することを防ぐことができます。

条件付き書き込みは、複数のユーザーが同じ項目を変更しようとする場合に役立ちます。2 人のユーザー (Alice と Bob) が DynamoDB テーブルから同じ項目を処理している以下の図を考慮します。

![Alice と Bob は、ID 1 の項目を変更しようとし、条件付き書き込みの必要性を示します。](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/update-no-condition.png)


Alice が AWS CLI を使用して `Price` 属性を 8 に更新するとします。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":newval":{"N":"8"}
}
```

次に、Bob が後で同様の `UpdateItem` リクエストを発行しますが、`Price` を 12 に変更します。Bob には、`--expression-attribute-values` パラメータは次のように見えます。

```
{
    ":newval":{"N":"12"}
}
```

Bob のリクエストは成功しますが、その前の Alice の更新は失われます。

条件付き `PutItem`、`DeleteItem`、または `UpdateItem` をリクエストするには、条件式を指定します。*条件式*は、属性名、条件付き演算子および組み込み関数を含む文字列です。式全体の評価が true になる必要があります。それ以外の場合は、このオペレーションは失敗します。

次は、条件付き書き込みにより Alice の更新が上書きされるのを防ぐ方法について、以下の図を考慮します。

![条件付き書き込みにより、ユーザー Bob の更新によってユーザー Alice の変更が同じ項目に上書きされるのを防ぐことができます。](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/update-yes-condition.png)


Alice はまず `Price` を 8 に更新を試行しますが、現在の `Price` が 10 である場合にのみ、という条件でそうします。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --condition-expression "Price = :currval" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":newval":{"N":"8"},
    ":currval":{"N":"10"}
}
```

条件が true に評価されるため、Alice の更新は成功します。

次に、Bob は、`Price` を 12 に 更新しますが、現在の `Price` が 10 である場合にのみ、という条件でそうします。Bob には、`--expression-attribute-values` パラメータは次のように見えます。

```
{
    ":newval":{"N":"12"},
    ":currval":{"N":"10"}
}
```

Alice がすでに `Price` を 8 に変更していたので、条件式は false 評価され Bob の更新は失敗します。

詳細については、「[DynamoDB 条件式 CLI の例](Expressions.ConditionExpressions.md)」を参照してください。

### 条件付き書き込みの冪等性
<a name="WorkingWithItems.ConditionalWrites.Idempotence"></a>

条件付き書き込みは、条件チェックが更新される同じ属性で行われる場合に、*べき等性*が保たれます。つまり、リクエスト時に項目の特定の属性値が想定されたものである場合にのみ、DynamoDB によって指定された書き込みリクエストが実行されます。

たとえば、`UpdateItem` リクエストを発行し、項目の `Price` を、現在の `Price` が 20 である場合のみ、3 増加させるとします。リクエストを送信した後、その結果を得る前にネットワークエラーが発生したため、リクエストが成功したかどうか不明です。この条件付き書き込みはべき等のオペレーションであるため、同じ `UpdateItem` リクエストを再試行できます。すると、DynamoDB は、現在の `Price` が 20 である場合のみ項目を更新します。

### 条件付き書き込みで消費されるキャパシティユニット
<a name="WorkingWithItems.ConditionalWrites.ReturnConsumedCapacity"></a>

条件付き書き込み中に `ConditionExpression` が false と評価された場合でも、DynamoDB はテーブルの書き込みキャパシティを消費します。消費量は、既存の項目のサイズ（または最低 1）によって異なります。例えば、既存の項目が 300 KB で、作成または更新しようとしている新しい項目が 310 KB の場合、消費される書き込みキャパシティーユニットは、条件が満たされないかったら 300、満たされたら 310 になります。これが新しい項目 (既存の項目なし) の場合、消費される書き込みキャパシティーユニットは条件が満たされれば 1、条件が満たされなかったら 310 になります。

**注記**  
書き込みオペレーションでは、*書き込み*キャパシティーユニットのみが消費されます。*読み込み*キャパシティーユニットは消費されません。

失敗した条件付き書き込みは `ConditionalCheckFailedException` を返します。これが起きると、消費された書き込みキャパシティに関する情報はレスポンスで返されません。

条件付き書き込みの際に消費された書き込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを使用します。
+ `TOTAL` — 消費された書き込み容量単位の総数を返します。
+ `INDEXES` — 消費された書き込み容量単位の総数とともに、テーブルおよびオペレーションに影響を受けたセカンダリインデックスの小計を返します。
+ `NONE` — 書き込み容量の詳細は返されません。(これがデフォルトです)

  

**注記**  
グローバルセカンダリインデックスとは異なり、ローカルセカンダリインデックスは、プロビジョンドスループット性能をそのテーブルと共有します。ローカルセカンダリインデックスでの読み込みと書き込みのアクティビティは、テーブルからプロビジョンドスループット性能を消費します。