

# SQL から NoSQL に移行する方法について学ぶ
<a name="SQLtoNoSQL"></a>

アプリケーションデベロッパーなら、リレーショナルデータベース管理システム (RDBMS) および構造化クエリ言語 (SQL) を使用した経験があるかもしれません。Amazon DynamoDB を使い始めると、多くの類似点があると同時に、異なる点も多くあることに気づきます。*NoSQL* は、可用性が高く、スケーラブルで、高パフォーマンス用に最適化された、非リレーショナルデータベースシステムについて説明するのに使用される用語です。NoSQL データベース (DynamoDB など) は、リレーショナルモデルの代わりに、キーバリューのペアやドキュメントストレージなど、データ管理のための代替モデルを使用します。詳細については、「[NoSQL とは](https://aws.amazon.com/nosql)」を参照してください。

Amazon DynamoDB は [PartiQL](https://partiql.org/) をサポートしています。PartiQL は、オープンソースの SQL 互換のクエリ言語で、データの格納場所や形式に関係なく、データへの効率的なクエリの実行が簡単に行えます。PartiQL を使用すると、リレーショナルデータベースの構造化データ、オープンデータ形式の半構造化データおよびネストされたデータ、さらには行ごとに異なる属性を許可する NoSQL またはドキュメントデータベース内のスキーマレスデータを簡単に処理できます。詳細については、「[PartiQL Query Language](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)」(PartiQL クエリ言語) を参照してください。

次のセクションでは、SQL ステートメントを同等の DynamoDB オペレーションと比較および対比しながら、一般的なデータベースタスクについて説明します。

**注記**  
このセクションの SQL の例は、MySQL の RDBMS と互換性があります。  
このセクションの DynamoDB 例では、JSON 形式のオペレーションのパラメータと共に DynamoDB オペレーションの名前を表示します。

**Topics**
+ [

# リレーショナル (SQL) または NoSQL の選択
](SQLtoNoSQL.WhyDynamoDB.md)
+ [

# リレーショナル (SQL) データベースと DynamoDB へのアクセスの相違点
](SQLtoNoSQL.Accessing.md)
+ [

# テーブル作成時のリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.CreateTable.md)
+ [

# リレーショナル (SQL) データベースと DynamoDB からテーブル情報を取得するときの相違点
](SQLtoNoSQL.GetTableInfo.md)
+ [

# テーブルにデータを書き込むときのリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.WriteData.md)
+ [

# テーブルからデータを読み込むときの、リレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.ReadData.md)
+ [

# インデックスを管理するときのリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.Indexes.md)
+ [

# テーブル内のデータを変更するときのリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.UpdateData.md)
+ [

# テーブルからデータを削除するときのリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.DeleteData.md)
+ [

# テーブルを削除するときのリレーショナル (SQL) データベースと DynamoDB の相違点
](SQLtoNoSQL.RemoveTable.md)

# リレーショナル (SQL) または NoSQL の選択
<a name="SQLtoNoSQL.WhyDynamoDB"></a>

現在のアプリケーションには今までになく厳しい要件があります。たとえば、あるオンラインゲームを、小数のユーザーおよび非常に小さいデータ量で開始するかもしれません。しかし、ゲームが成功すれば、それは基盤となるデータベース管理システムのリソースを簡単に上回ります。ウェブベースのアプリケーションに、数百、数千、数百万の同時ユーザーがいて、テラバイトあるいはそれ以上の新しいデータが毎日生成される、というのはよくあることです。そのようなアプリケーションのデータベースの場合は、1 秒あたり数万 (あるいは数十万) の読み取り/書き込みの処理が必要です。

Amazon DynamoDB は、これらのワークロードに適しています。デベロッパーとして、アプリケーションを小さく開始し、人気が出るにつれて徐々に増加させることができます。DynamoDB は、大量のデータや多数のユーザーの処理をシームレスにスケーリングします。

従来のリレーショナルデータベースモデリングと DynamoDB に適応させる方法の詳細については、「[DynamoDB でリレーショナルデータをモデル化するためのベストプラクティス](bp-relational-modeling.md)」を参照してください。

次の表に、リレーショナルデータベース管理システム (RDBMS) と DynamoDB の高度な相違点を示します。


****  

| 特性 | リレーショナルデータベース管理システム (RDBMS) | Amazon DynamoDB | 
| --- | --- | --- | 
| 最適なワークロード | アドホッククエリ、データウェアハウス、OLAP (オンライン分析処理)。 | ソーシャルネットワーク、ゲーム、メディア共有、Internet of Things (IoT) を含む、ウェブスケールアプリケーションです。 | 
| データモデル | リレーショナルモデルには、データを、テーブル、行、列に正規化する、明確に定義されたスキーマが必要です。さらに、関係のすべては、テーブル、列、インデックスおよび他のデータベースのエレメント間で定義されます。 | DynamoDB はスキーマレスです。すべてのテーブルに、各データ項目を一意に識別するプライマリキーが必要ですが、他の非キー属性のような制約はありません。DynamoDB では、JSON ドキュメントを含む構造化データまたは半構造化データを管理できます。 | 
| データアクセス | SQL は、データを保存および取得するための基準です。リレーショナルデータベースにはデータベース駆動型アプリケーションの開発を簡素化するためのツールが豊富ですが、これらのツールはすべて、SQL を使用します。 | AWS マネジメントコンソール、AWS CLI、または NoSQL WorkBench を使用して DynamoDB を操作し、アドホックタスクを実行できます。[PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) は SQL 互換のクエリ言語であり、DynamoDB でデータの選択、挿入、更新、および削除を行うことができます。アプリケーションでは、オブジェクトベースでドキュメント中心、または低レベルのインターフェイスを使用しながら、AWS ソフトウェア開発キット (SDK) を活用し、DynamoDB を操作できます。 | 
| パフォーマンス | リレーショナルデータベースは、ストレージに最適化されていますので、パフォーマンスは通常、ディスクサブシステムによって異なります。デベロッパーとデータベース管理者は、ピークパフォーマンスを達成するために、クエリ、インデックスおよびテーブルの構造を最適化する必要があります。 | DynamoDB は、コンピューティングに最適化されていますので、パフォーマンスは主に、基盤となるハードウェアとネットワークレイテンシーの機能です。マネージドサービスとして、DynamoDB は、これらの実装の詳細からアプリケーションを隔離し、堅牢で高パフォーマンスなアプリケーションの設計と構築に集中できるようにします。 | 
| スケーリング | より高速なハードウェアでスケールアップするのが最も簡単です。データベーステーブルが分散システムの複数のホストにまたがることは可能ですが、この場合、追加の投資が必要です。リレーショナルデータベースは、スケーラビリティに上限を課すファイルの数とサイズが最大サイズです。 | DynamoDB は、ハードウェアの分散型クラスターを使用してスケールアウトできるように設計されています。この設計により、レイテンシーの増加なしでスループットを強化することができます。顧客がスループット要件を指定すると、DynamoDB は、その要件に対応するために十分なリソースを割り当てます。テーブル単位の項目数、およびそのテーブルの合計サイズに上限はありません。 | 

# リレーショナル (SQL) データベースと DynamoDB へのアクセスの相違点
<a name="SQLtoNoSQL.Accessing"></a>

アプリケーションがデータベースにアクセスする前に、アプリケーションがデータベースの使用を許可されるように*認証*する必要があります。アプリケーションで、許可されているアクションのみ実行できるように、*許可*する必要があります。

次の図表は、クライアントのリレーショナルデータベースおよび Amazon DynamoDB とのやり取りを示します。

![\[リレーショナルおよび NoSQL データベースとのやり取り。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/SQLtoNoSQL.png)


次の表にクライアントのやり取りのタスクについての詳細があります。


****  

| 特徴 | リレーショナルデータベース管理システム (RDBMS) | Amazon DynamoDB | 
| --- | --- | --- | 
| データベースにアクセスするためのツール |  ほとんどのリレーショナルデータベースは、コマンドラインインターフェイス (CLI) を提供しており、アドホックな SQL ステートメントを入力して、結果をすぐに見ることができます。  | ほとんどの場合、アプリケーションコードを書き込みます。AWS マネジメントコンソール、AWS Command Line Interface (AWS CLI)、または NoSQL Workbench を使用して、アドホックリクエストを DynamoDB に送信し、結果を表示することもできます。[PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) は SQL 互換のクエリ言語であり、DynamoDB でデータの選択、挿入、更新、および削除を行うことができます。 | 
| データベースに接続 | アプリケーションプログラムは、データベースを使用したネットワーク接続を確立し、維持します。アプリケーションが終了すると、接続を終了します。 | DynamoDB は、ウェブサービスで、その操作はステートレスです。アプリケーションは永続的ネットワーク接続を維持する必要はありません。代わりに、DynamoDB の操作は HTTP(S) リクエストおよびレスポンスを使用して行われます。 | 
| 認証 | アプリケーションが認証されるまでデータベースに接続できません。RDBMS は認証自体を実行できますし、ホストのオペレーティングシステムやディレクトリサービスにこのタスクをオフロードすることもできます。 | DynamoDB に対するすべてのリクエストは、その特定のリクエストを認証する暗号署名と共に使用しなければなりません。AWS SDK は、署名の作成とリクエストの署名に必要なすべての論理を提供します。詳細については、「AWS 全般のリファレンス.」の「[AWS API リクエストの署名](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)」を参照してください。 | 
| Authorization | アプリケーションは承認されたアクションのみ実行できます。データベース管理者またはアプリケーション所有者は、SQL GRANT および REVOKE ステートメントを使用して、データベースオブジェクト (テーブルなど)、データ (テーブル内の行など)、特定の SQL ステートメントを発行する機能へのアクセスを制御できます。 | DynamoDB では、AWS Identity and Access Management (IAM) が承認を行います。DynamoDB リソース (テーブルなど) へのアクセス許可を付与する IAM ポリシーを記述し、ユーザーとロールがそのポリシーを使用できるようにします。IAM では、DynamoDB テーブルの個々のデータ項目に対する詳細なアクセス制御といった特徴も備えています。詳細については、「[Amazon DynamoDB の Identity and Access Management](security-iam.md)」を参照してください。 | 
| リクエストを送信 | アプリケーションは、実行するすべてのデータベース操作に対する SQL ステートメントを発行します。SQL ステートメントを受信すると、RDBMS は構文を確認し、オペレーションを実行するための計画を作成してから、計画を実行します。 | アプリケーションは、HTTP(S) リクエストを DynamoDB に送信します。リクエストには、パラメータとともに、実行する DynamoDB オペレーションの名前が含まれます。DynamoDB はリクエストを直ちに実行します。 | 
| レスポンスを受信 | RDBMS は SQL ステートメントから結果を返します。エラーがある場合は、RDBMS はエラー状況とエラーメッセージを返します。 | DynamoDB は、オペレーションの結果を含む HTTP(S) レスポンスを返します。エラーがあると、DynamoDB は、HTTP エラー状況およびエラーメッセージを返します。 | 

# テーブル作成時のリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.CreateTable"></a>

テーブルは、リレーショナルデータベースおよび Amazon DynamoDB の基本的なデータ構造です。リレーショナルデータベース管理システム (RDBMS) では、作成時に、テーブルのスキーマを定義する必要があります。対照的に、DynamoDB テーブルはスキーマレスであるため、プライマリキーを除いて、テーブルを作成する際に、追加の属性やデータ型を定義する必要はありません。

次のセクションでは、SQL を使用してテーブルを作成する方法と、DynamoDB を使用してテーブルを作成する方法を比較します。

**Topics**
+ [

## SQL を使用してテーブルを作成する
](#SQLtoNoSQL.CreateTable.SQL)
+ [

## DynamoDB を使用してテーブルを作成する
](#SQLtoNoSQL.CreateTable.DynamoDB)

## SQL を使用してテーブルを作成する
<a name="SQLtoNoSQL.CreateTable.SQL"></a>

SQL では、次の例に示すように、`CREATE TABLE` ステートメントを使用して、テーブルを作成します。

```
CREATE TABLE Music (
    Artist VARCHAR(20) NOT NULL,
    SongTitle VARCHAR(30) NOT NULL,
    AlbumTitle VARCHAR(25),
    Year INT,
    Price FLOAT,
    Genre VARCHAR(10),
    Tags TEXT,
    PRIMARY KEY(Artist, SongTitle)
);
```

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。

テーブルの列とデータ型すべて、およびテーブルのプライマリキーを定義する必要があります。(これらの定義は、`ALTER TABLE` ステートメントを使用して、必要に応じて後で変更することができます。)

多くの SQL 実装では、`CREATE TABLE` ステートメントの一部として、テーブルのストレージ仕様を定義することができます。他に明記されていない限り、テーブルはデフォルトのストレージ設定で作成されます。本稼働環境では、データベース管理者は最適なストレージパラメータを特定することもできます。

## DynamoDB を使用してテーブルを作成する
<a name="SQLtoNoSQL.CreateTable.DynamoDB"></a>

`CreateTable` オペレーションを使用してプロビジョニングモードのテーブルを作成し、次に示すように、パラメータを指定します。

```
{
    TableName : "Music",
    KeySchema: [
        {
            AttributeName: "Artist",
            KeyType: "HASH" //Partition key
        },
        {
            AttributeName: "SongTitle",
            KeyType: "RANGE" //Sort key
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: "Artist",
            AttributeType: "S"
        },
        {
            AttributeName: "SongTitle",
            AttributeType: "S"
        }
    ],
    ProvisionedThroughput: {       // Only specified if using provisioned mode
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1
    }
}
```

このテーブルのプライマリキーは、*Artist* (パーティションキー) および *SongTitle* (ソートキー) で構成されています。

`CreateTable` に以下のパラメータを提供する必要があります。
+ `TableName` – テーブルの名前。
+ `KeySchema` – プライマリキーに使用する属性。詳細については、「[テーブル、項目、属性](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.TablesItemsAttributes)」および「[プライマリキー](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.PrimaryKey)」を参照してください。
+ `AttributeDefinitions` – キースキーマ属性のデータ型。
+ `ProvisionedThroughput (for provisioned tables)` – このテーブルに必要な 1 秒あたりの読み取り/書き込み数。DynamoDB は、スループット要件を常に満たすように、十分なストレージとシステムリソースを確保しています。これらは、`UpdateTable` オペレーションを使用し、必要に応じて後で変更できます。DynamoDB がストレージ割り当てを完全に管理しているため、テーブルのストレージ要件を指定する必要はありません。

# リレーショナル (SQL) データベースと DynamoDB からテーブル情報を取得するときの相違点
<a name="SQLtoNoSQL.GetTableInfo"></a>

テーブルが仕様に従って作成されたことを確認できます。リレーショナルデータベースでは、テーブルのスキーマがすべて表示されます。Amazon DynamoDB テーブルはスキーマレスであるため、プライマリキー属性のみが表示されます。

**Topics**
+ [

## SQL を使ってテーブルに関する情報を取得する
](#SQLtoNoSQL.GetTableInfo.SQL)
+ [

## DynamoDB でテーブルに関する情報を取得する
](#SQLtoNoSQL.GetTableInfo.DynamoDB)

## SQL を使ってテーブルに関する情報を取得する
<a name="SQLtoNoSQL.GetTableInfo.SQL"></a>

ほとんどのリレーショナルデータベース管理システム (RDBMS) では、テーブルの構造 (列、データ型、プライマリキー定義など) を記述できます。SQL にはこれを行うための標準的な方法はありません。ただし、データベースシステムの多くが `DESCRIBE` コマンドを提供しています。MySQL の例を以下に示します。

```
DESCRIBE Music;
```

すべての列名、データ型、サイズを含むテーブルの構造が返ります。

```
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| Artist     | varchar(20) | NO   | PRI | NULL    |       |
| SongTitle  | varchar(30) | NO   | PRI | NULL    |       |
| AlbumTitle | varchar(25) | YES  |     | NULL    |       |
| Year       | int(11)     | YES  |     | NULL    |       |
| Price      | float       | YES  |     | NULL    |       |
| Genre      | varchar(10) | YES  |     | NULL    |       |
| Tags       | text        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
```

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。

## DynamoDB でテーブルに関する情報を取得する
<a name="SQLtoNoSQL.GetTableInfo.DynamoDB"></a>

DynamoDB には、同様の `DescribeTable` オペレーションがあります。パラメータは、テーブル名のみです。

```
{
    TableName : "Music"
}
```

`DescribeTable` からの返信は、次のようになります。

```
{
  "Table": {
    "AttributeDefinitions": [
      {
        "AttributeName": "Artist",
        "AttributeType": "S"
      },
      {
        "AttributeName": "SongTitle",
        "AttributeType": "S"
      }
    ],
    "TableName": "Music",
    "KeySchema": [
      {
        "AttributeName": "Artist",
        "KeyType": "HASH"  //Partition key
      },
      {
        "AttributeName": "SongTitle",
        "KeyType": "RANGE"  //Sort key
      }
    ],

    ...
```

`DescribeTable` は、テーブルのインデックス、プロビジョニングされたスループット設定、概算項目数、その他メタデータに関する情報を返します。

# テーブルにデータを書き込むときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.WriteData"></a>

リレーショナルデータベースのテーブルには、データの*行*が含まれます。行は*列*で構成されます。Amazon DynamoDB テーブルには、*項目*が含まれています。項目は*属性*で構成されます。

このセクションでは、テーブルに 1 つの行 (または項目) を書き込む方法を説明します。

**Topics**
+ [

## SQL を使ってテーブルにデータを書き込む
](#SQLtoNoSQL.WriteData.SQL)
+ [

## DynamoDB のテーブルにデータを書き込む
](#SQLtoNoSQL.WriteData.DynamoDB)

## SQL を使ってテーブルにデータを書き込む
<a name="SQLtoNoSQL.WriteData.SQL"></a>

リレーショナルデータベースのテーブルは、行と列で構成される、2 つのディメンションのデータ構造です。一部のデータベース管理システムは、通常、ネイティブ JSON または XML データ型を使用する半構造化データのサポートを提供します。ただし、実装の詳細はベンダー間で変わります。

SQL では、`INSERT` ステートメントを使用して、テーブルに行を追加します。

```
INSERT INTO Music
    (Artist, SongTitle, AlbumTitle,
    Year, Price, Genre,
    Tags)
VALUES(
    'No One You Know', 'Call Me Today', 'Somewhat Famous',
    2015, 2.14, 'Country',
    '{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}'
);
```

このテーブルのプライマリキーは、*Artist* と *SongTitle* で構成されます。これらの列の値を指定する必要があります。

**注記**  
この例では、*Tags* 列を使用して、*Music* テーブル内の曲に関する半構造化データを保存します。*Tags* 列は TEXT 型として定義され、MySQL で最大 65,535 文字を保存できます。

## DynamoDB のテーブルにデータを書き込む
<a name="SQLtoNoSQL.WriteData.DynamoDB"></a>

Amazon DynamoDB では、DynamoDB API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、テーブルに項目を追加できます。

------
#### [ DynamoDB API ]

DynamoDB API では、`PutItem` オペレーションを使用して、テーブルに項目を追加します。

```
{
    TableName: "Music",
    Item: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today",
        "AlbumTitle":"Somewhat Famous",
        "Year": 2015,
        "Price": 2.14,
        "Genre": "Country",
        "Tags": {
            "Composers": [
                  "Smith",
                  "Jones",
                  "Davis"
            ],
            "LengthInSeconds": 214
        }
    }
}
```

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。これらの属性の値を指定する必要があります。

この `PutItem` 例に関する主要事項を示します。
+ DynamoDB では、JSON を使用して、ドキュメントのネイティブサポートを提供しています。これにより DynamoDB は *Tags* などの半構造化データを保存する場合に最適になります。また、JSON ドキュメント内からデータを取得および操作できます。
+ *Music* テーブルには、プライマリキー (*Artist* および *SongTitle*) 以外には事前定義された属性はありません。
+ ほとんどの SQL データベースはトランザクション指向です。`INSERT` ステートメントを発行すると、データ変更は、`COMMIT` ステートメントを発行するまで永続的ではありません。Amazon DynamoDB によって、`PutItem` オペレーションの効果は、DynamoDB が HTTP 200 ステータスコード (`OK`) で応答する場合、永続的になります。

次に、`PutItem` の他の例をいくつか示します。

```
{
    TableName: "Music",
    Item: {
        "Artist": "No One You Know",
        "SongTitle": "My Dog Spot",
        "AlbumTitle":"Hey Now",
        "Price": 1.98,
        "Genre": "Country",
        "CriticRating": 8.4
    }
}
```

```
{
    TableName: "Music",
    Item: {
        "Artist": "No One You Know",
        "SongTitle": "Somewhere Down The Road",
        "AlbumTitle":"Somewhat Famous",
        "Genre": "Country",
        "CriticRating": 8.4,
        "Year": 1984
    }
}
```

```
{
    TableName: "Music",
    Item: {
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love",
        "AlbumTitle":"The Buck Starts Here",
        "Price": 2.47,
        "Genre": "Rock",
        "PromotionInfo": {
            "RadioStationsPlaying":[
                 "KHCR", "KBQX", "WTNR", "WJJH"
            ],
            "TourDates": {
                "Seattle": "20150625",
                "Cleveland": "20150630"
            },
            "Rotation": "Heavy"
        }
    }
}
```

```
{
    TableName: "Music",
    Item: {
        "Artist": "The Acme Band",
        "SongTitle": "Look Out, World",
        "AlbumTitle":"The Buck Starts Here",
        "Price": 0.99,
        "Genre": "Rock"
    }
}
```

**注記**  
`PutItem` に加えて、DynamoDB は、同時に複数の項目に書き込むための `BatchWriteItem` オペレーションもサポートします。

------
#### [ PartiQL for DynamoDB ]

PartiQL では、PartiQL `ExecuteStatement` ステートメントを利用する `Insert` オペレーションを使用して、テーブルに項目を追加します。

```
INSERT into Music value {  
    'Artist': 'No One You Know',
    'SongTitle': 'Call Me Today',
    'AlbumTitle': 'Somewhat Famous',
    'Year' : '2015',
    'Genre' : 'Acme'
}
```

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。これらの属性の値を指定する必要があります。

**注記**  
`Insert` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL 挿入ステートメント](ql-reference.insert.md) を参照してください。

------

# テーブルからデータを読み込むときの、リレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.ReadData"></a>

SQL では、`SELECT` ステートメントを使用して、テーブルから 1 つ以上の行を取得します。`WHERE` 句を使用して、返されたデータを調べます。

これは、Amazon DynamoDB を使用する場合とは異なります。Amazon DynamoDb は、データの読み取りに次のオペレーションを提供します。
+ `ExecuteStatement` がテーブルから 1 つまたは複数の項目を取得します。`BatchExecuteStatement` が 1 回のオペレーションで異なるテーブルから複数の項目を取得します。どちらのオペレーションでも、SQL 互換のクエリ言語である [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) が使用されます。
+ `GetItem` – テーブルから単一の項目を取り出します。これは、項目の物理的な場所に直接アクセスできるため、単一の項目を読み込むうえで最も効率的な方法です。(DynamoDB では、`BatchGetItem` オペレーションを提供し、1 回のオペレーションで最大 100 回の `GetItem` コールを実行できます。)
+ `Query` – 特定のパーティションキーがあるすべての項目を取得します。これらの項目内では、ソートキーに条件を適用し、データのサブセットのみ取得できます。`Query` は、データが格納されているパーティションに、すばやく効率的にアクセスできます。（詳しくは、[DynamoDB におけるパーティションとデータ分散](HowItWorks.Partitions.md) を参照してください）。
+ `Scan` – 指定されたテーブルで、すべての項目を取得します。(大量のリソースシステムを消費するため、このオペレーションは大きなテーブルでは使用しないでください。)

**注記**  
リレーショナルデータベースでは、`SELECT` ステートメントを使用して、複数のテーブルからデータを結合し、その結果を返すことができます。結合は、リレーショナルモデルにおいて必須です。結合を効率的に実行するために、データベースおよびアプリケーションは、継続的にパフォーマンスを調整する必要があります。DynamoDB は、テーブル結合をサポートしない非リレーショナル NoSQL データベースです。その代わり、アプリケーションは一度に 1 つのテーブルからデータを読み込みます。

次のセクションでは、データを読み込むための異なるユースケースおよびこれらのタスクをリレーショナルデータベースと DynamoDB を使って実行する方法を説明します。

**Topics**
+ [

# プライマリキーを使用して項目を読み込むときの相違点
](SQLtoNoSQL.ReadData.SingleItem.md)
+ [

# テーブルのクエリにおける相違点
](SQLtoNoSQL.ReadData.Query.md)
+ [

# テーブルのスキャンにおける相違点
](SQLtoNoSQL.ReadData.Scan.md)

# プライマリキーを使用して項目を読み込むときの相違点
<a name="SQLtoNoSQL.ReadData.SingleItem"></a>

データベースの一般的なアクセスパターンの 1 つは、テーブルから単一項目を読み取ることです。目的の項目のプライマリキーを指定する必要があります。

**Topics**
+ [

## SQL にプライマリキーを使用して項目を読み込む
](#SQLtoNoSQL.ReadData.SingleItem.SQL)
+ [

## DynamoDB でプライマリキーを使用して項目を読み込む
](#SQLtoNoSQL.ReadData.SingleItem.DynamoDB)

## SQL にプライマリキーを使用して項目を読み込む
<a name="SQLtoNoSQL.ReadData.SingleItem.SQL"></a>

SQL では、`SELECT` ステートメントを使用して、テーブルからデータを取得します。結果の 1 つ以上の列 (`*` オペレーター を使用すれば、すべて) をリクエストできます。`WHERE` 句は返る行を判別します。

以下は、*Music* テーブルから単一の行を取得するための `SELECT` ステートメントです。`WHERE` 句はプライマリキー値を指定します。

```
SELECT *
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

列のサブセットのみを取得するようにこのクエリを変更できます。

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

このテーブルのプライマリキーが、*Artist* および *SongTitle* で構成されていることに注意してください。

## DynamoDB でプライマリキーを使用して項目を読み込む
<a name="SQLtoNoSQL.ReadData.SingleItem.DynamoDB"></a>

Amazon DynamoDB では、DynamoDB API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、テーブルから項目を読み込むことができます。

------
#### [ DynamoDB API ]

DynamoDB API では、`PutItem` オペレーションを使用して、テーブルに項目を追加します。

DynamoDB は、プライマリキーにより項目を取得するための `GetItem` オペレーションを提供します。`GetItem` は、項目の物理的な場所への直接アクセスを提供するため非常に効率的です。（詳しくは、[DynamoDB におけるパーティションとデータ分散](HowItWorks.Partitions.md) を参照してください）。

デフォルトでは、`GetItem` は、すべての属性を含む項目全体を返します。

```
{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    }
}
```

一部の属性のみが返されるように、`ProjectionExpression` パラメータを追加できます。

```
{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    },
    "ProjectionExpression": "AlbumTitle, Year, Price"
}
```

このテーブルのプライマリキーが、*Artist* および *SongTitle* で構成されていることに注意してください。

DynamoDB `GetItem` オペレーションは非常に効率的です。プライマリキー値を使用して、該当する項目の正確な格納場所を特定し、そこから直接取得します。SQL `SELECT` ステートメントは、プライマリキー値によって項目を取得する場合、同様に効率的です。

SQL `SELECT` ステートメントは、さまざまな種類のクエリとテーブルスキャンをサポートしています。DynamoDB は、[テーブルのクエリにおける相違点](SQLtoNoSQL.ReadData.Query.md) および [テーブルのスキャンにおける相違点](SQLtoNoSQL.ReadData.Scan.md) で説明されている `Query` および `Scan` オペレーションと同様の機能を提供します。

SQL `SELECT` ステートメントは、テーブルの結合を実行でき、同時に複数のテーブルからデータを取得できます。データベーステーブルが正規化され、テーブル間の関係が明確である場合、結合は最も効果的です。ただし、1 つの `SELECT`ステートメントであまりに多くのテーブルを結合すると、アプリケーションパフォーマンスが影響を受けます。データベースレプリケーション、マテリアライズドビュー、またはクエリの書き換えを使用して、このような問題を回避できます。

DynamoDB は、非リレーショナルデータベースのため、テーブルの結合はサポートされません。リレーショナルデータベースから既存のアプリケーションを DynamoDB に移行する場合、結合の必要を排除するためデータモデルを非正規化する必要があります。

------
#### [ PartiQL for DynamoDB ]

PartiQL では、PartiQL `Select` ステートメントを利用する `ExecuteStatement` オペレーションを使用して、テーブルから項目を読みます。

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

このテーブルのプライマリキーが、Artist および SongTitle で構成されていることに注意してください。

**注記**  
 選択 PartiQL ステートメントは、DynamoDB テーブルにクエリやスキャンを実行する場合にも使用できます

`Select` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL select ステートメント](ql-reference.select.md) を参照してください。

------

# テーブルのクエリにおける相違点
<a name="SQLtoNoSQL.ReadData.Query"></a>

もう 1 つの一般的なアクセスパターンは、クエリ条件に基づき、テーブルから複数の項目を読み込むことです。

**Topics**
+ [

## SQL を使用してテーブルのクエリを実行する
](#SQLtoNoSQL.ReadData.Query.SQL)
+ [

## DynamoDB でテーブルのクエリを実行する
](#SQLtoNoSQL.ReadData.Query.DynamoDB)

## SQL を使用してテーブルのクエリを実行する
<a name="SQLtoNoSQL.ReadData.Query.SQL"></a>

SQL を使用すると、`SELECT` ステートメントは、キー列、非キー列、または任意の組み合わせに対してクエリを実行できます。`WHERE` 句は、次の例に示すように、返る行を決定します。

```
/* Return a single song, by primary key */

SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today';
```

```
/* Return all of the songs by an artist */

SELECT * FROM Music
WHERE Artist='No One You Know';
```

```
/* Return all of the songs by an artist, matching first part of title */

SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%';
```

```
/* Return all of the songs by an artist, only if the price is less than 1.00 */

SELECT * FROM Music
WHERE Artist='No One You Know'
AND Price < 1.00;
```

このテーブルのプライマリキーが、*Artist* および *SongTitle* で構成されていることに注意してください。

## DynamoDB でテーブルのクエリを実行する
<a name="SQLtoNoSQL.ReadData.Query.DynamoDB"></a>

Amazon DynamoDB では、DynamoDB API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、テーブルの項目にクエリを実行できます。

------
#### [ DynamoDB API ]

Amazon DynamoDB では、`Query` オペレーションを使用すると、同様の方法でデータを取得できます。`Query` オペレーションは、データが保存されている物理的な場所にすばやく効率的にアクセスすることができます。詳細については、「[DynamoDB におけるパーティションとデータ分散](HowItWorks.Partitions.md)」を参照してください。

`Query` は任意のテーブルまたはセカンダリインデックスでを使用できます。パーティションキーの値に対して等価条件を指定する必要があります。ソートキー属性が定義されている場合は、必要に応じて別の条件を指定できます。

`KeyConditionExpression` パラメータは、クエリを実行するキー値を指定します。オプションの `FilterExpression` を使用して、結果が返される前に、そこから特定の項目を削除できます。

DynamoDB では、式パラメータ (`KeyConditionExpression` や `FilterExpression` など) で `ExpressionAttributeValues` をプレースホルダーとして使用する必要があります。これは、ランタイム時に実際の値を `SELECT` ステートメントに代入する、リレーショナルデータベースでの*バインド変数*の使用に類似しています。

このテーブルのプライマリキーが、*Artist* および *SongTitle* で構成されていることに注意してください。

次に、DynamoDB `Query` の例をいくつか示します。

```
// Return a single song, by primary key

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a and SongTitle = :t",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":t": "Call Me Today"
    }
}
```

```
// Return all of the songs by an artist

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a",
    ExpressionAttributeValues: {
        ":a": "No One You Know"
    }
}
```

```
// Return all of the songs by an artist, matching first part of title

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a and begins_with(SongTitle, :t)",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":t": "Call"
    }
}
```

```
// Return all of the songs by an artist, only if the price is less than 1.00

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a",
    FilterExpression: "Price < :p",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":p": 1.00
    }
}
```

**注記**  
`FilterExpression` は、`Query` が一致する項目を読み取った後に適用されるため、消費される読み取り容量は減少しません。可能な場合は、効率的なクエリのために範囲条件でソートキーに対して `KeyConditionExpression` を使用するようにデータをモデル化します。詳細については、「[DynamoDB のテーブルに対するクエリの実行](Query.md)」を参照してください。

------
#### [ PartiQL for DynamoDB ]

PartiQL では、パーティションキーの `ExecuteStatement` オペレーションと `Select` ステートメントを使用してクエリを実行できます。

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know'
```

このように `SELECT` ステートメントを使用すると、この特定の `Artist` に関連付けられているすべての曲が返されます。

`Select` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL select ステートメント](ql-reference.select.md) を参照してください。

------

# テーブルのスキャンにおける相違点
<a name="SQLtoNoSQL.ReadData.Scan"></a>

SQL では、`SELECT` 句なしの `WHERE` ステートメントは、テーブルのすべての行を返します。Amazon DynamoDB では、`Scan` オペレーションで同様のアクションを行います。どちらの場合も、すべて、または一部の項目を取得できます。

SQL または NoSQL データベースのいずれを使用するにしても、スキャンは大量のシステムリソースを消費するので、控え目に使用する必要があります。スキャンが適切 (小さなテーブルをスキャンするなど) または不可避 (データの一括エクスポートの実行など) な場合はあります。しかし、一般的なルールとして、スキャンを実行しないようアプリケーションを設計する必要があります。詳細については、「[DynamoDB のテーブルに対するクエリの実行](Query.md)」を参照してください。

**注記**  
一括エクスポートを実行すると、パーティションごとに少なくとも 1 つのファイルも作成されます。各ファイル内のすべての項目は、その特定のパーティションのハッシュされたキースペースからのものです。

**Topics**
+ [

## SQL を使用してテーブルをスキャンする
](#SQLtoNoSQL.ReadData.Scan.SQL)
+ [

## DynamoDB でテーブルをスキャンする
](#SQLtoNoSQL.ReadData.Scan.DynamoDB)

## SQL を使用してテーブルをスキャンする
<a name="SQLtoNoSQL.ReadData.Scan.SQL"></a>

SQL を使用すると、`SELECT` 句を指定せずに、`WHERE` ステートメントを使用してテーブルをスキャンし、データのすべてを取得することができます。結果の 1 つ以上の列をリクエストできます。または、ワイルドカード文字「\$1」を使用する場合は、すべての項目をリクエストできます。

以下は `SELECT` ステートメントの使用例です。

```
/* Return all of the data in the table */
SELECT * FROM Music;
```

```
/* Return all of the values for Artist and Title */
SELECT Artist, Title FROM Music;
```

## DynamoDB でテーブルをスキャンする
<a name="SQLtoNoSQL.ReadData.Scan.DynamoDB"></a>

Amazon DynamoDB では、DynamoDB API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、テーブルに対してスキャンを実行します。

------
#### [ DynamoDB API ]

DynamoDB API では、テーブルまたはセカンダリインデックスの各項目にアクセスして、1 つまたは複数の項目または項目属性を返す `Scan` オペレーションを使用します。

```
// Return all of the data in the table
{
    TableName:  "Music"
}
```

```
// Return all of the values for Artist and Title
{
    TableName:  "Music",
    ProjectionExpression: "Artist, Title"
}
```

`Scan` オペレーションでは、`FilterExpression` パラメータも指定できます。これを使用して、結果に表示しない項目を破棄することができます。`FilterExpression` は、スキャンの実行後、結果が返されるまでの間に適用されます。(これは、大きなテーブルではお勧めしません。返される一致項目がごく少数でも、`Scan` 全体に対して料金が請求されます。)

------
#### [ PartiQL for DynamoDB ]

PartiQL では、`Select` ステートメントを使用するテーブルに対してすべての内容を返す `ExecuteStatement` オペレーションを使用してスキャンを実行します。

```
SELECT AlbumTitle, Year, Price
FROM Music
```

このステートメントは、Music テーブルのすべての項目を返すことに注意してください。

`Select` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL select ステートメント](ql-reference.select.md) を参照してください。

------

# インデックスを管理するときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.Indexes"></a>

インデックスは代替のクエリパターンへのアクセスを付与し、クエリを高速化できます。このセクションでは、SQL と Amazon DynamoDB におけるインデックスの作成と使用を比較します。

リレーショナルデータベースまたは DynamoDB のいずれを使用するにしても、インデックスの作成は慎重に判断する必要があります。テーブルに書き込みが発生するたびに、テーブルのインデックスはすべて、更新する必要があります。大きなテーブルでの書き込み量が多い環境では、大量のシステムリソースを消費する可能性があります。読み取り専用または読み取りがほとんどの環境では、これは大きな問題にはなりません。ただし、インデックスがアプリケーションによって実際に使用されており、ただ容量を取っていることがないよう確認する必要があります。

**Topics**
+ [

## インデックスを作成するときのリレーショナル (SQL) データベースと DynamoDB の相違点
](#SQLtoNoSQL.Indexes.Creating)
+ [

## インデックスのクエリとスキャンをするときのリレーショナル (SQL) データベースと DynamoDB の相違点
](#SQLtoNoSQL.Indexes.QueryAndScan)

## インデックスを作成するときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.Indexes.Creating"></a>

SQL の `CREATE INDEX` ステートメントを Amazon DynamoDB の `UpdateTable` オペレーションと比較します。

**Topics**
+ [

### SQL を使ってインデックスを作成する
](#SQLtoNoSQL.Indexes.Creating.SQL)
+ [

### DynamoDB でインデックスを作成する
](#SQLtoNoSQL.Indexes.Creating.DynamoDB)

### SQL を使ってインデックスを作成する
<a name="SQLtoNoSQL.Indexes.Creating.SQL"></a>

リレーショナルデータベースのインデックスは、テーブルの異なる列に対して高速にクエリを実行できるデータ構造です。`CREATE INDEX` SQL ステートメントを使用して、既存のテーブルにインデックスが追加し、インデックスを作成する列を指定します。インデックスの作成後は、通常どおりテーブルのデータにクエリを実行できますが、テーブル全体をスキャンする代わりに、テーブルの指定された行を迅速に検索するため、データベースがインデックスを使用することができます。

インデックスの作成後は、データベースが維持します。テーブルのデータを変更した場合は、インデックスが自動的に変更され、テーブル内の変更を反映します。

MySQL では、次のようなインデックスを作成します。

```
CREATE INDEX GenreAndPriceIndex
ON Music (genre, price);
```

### DynamoDB でインデックスを作成する
<a name="SQLtoNoSQL.Indexes.Creating.DynamoDB"></a>

DynamoDB では、同様の目的のために、*セカンダリインデックス*を作成して使用できます。

DynamoDB のインデックスはリレーショナルな対応物とは異なります。セカンダリインデックスを作成する際、そのキー属性 (パーティションキーとソートキー) を指定する必要があります。セカンダリインデックスを作成したら、テーブルと同じように `Query` または `Scan` を実行できます。DynamoDB にはクエリオプティマイザーがないため、セカンダリインデックスは `Query` または `Scan` の場合にのみ使用されます。

DynamoDB では、次の 2 種類のインデックスをサポートしています。
+ グローバルセカンダリインデックス – インデックスのプライマリキーは、テーブルからの任意の 2 つの属性になります。
+ ローカルセカンダリインデックス – インデックスのパーティションキーは、テーブルのパーティションキーと同じである必要があります。ただし、ソートキーは、他の任意の属性にすることができます。

DynamoDB を使えば、セカンダリインデックスのデータは結果的にテーブルと整合性が取れます。テーブルまたはローカルセカンダリインデックスでの強い整合性を持つ `Query` または `Scan` オペレーションをリクエストできます。ただし、グローバルセカンダリインデックスは結果整合性のみをサポートします。

`UpdateTable` オペレーションを使用し、`GlobalSecondaryIndexUpdates` を指定して、既存のテーブルにグローバルセカンダリインデックスを追加できます。

```
{
    TableName: "Music",
    AttributeDefinitions:[
        {AttributeName: "Genre", AttributeType: "S"},
        {AttributeName: "Price", AttributeType: "N"}
    ],
    GlobalSecondaryIndexUpdates: [
        {
            Create: {
                IndexName: "GenreAndPriceIndex",
                KeySchema: [
                    {AttributeName: "Genre", KeyType: "HASH"}, //Partition key
                    {AttributeName: "Price", KeyType: "RANGE"}, //Sort key
                ],
                Projection: {
                    "ProjectionType": "ALL"
                },
                ProvisionedThroughput: {                                // Only specified if using provisioned mode
                    "ReadCapacityUnits": 1,"WriteCapacityUnits": 1
                }
            }
        }
    ]
}
```

`UpdateTable` に以下のパラメータを提供する必要があります。
+ `TableName` – インデックスが関連付けられるテーブル。
+ `AttributeDefinitions` – インデックスのキースキーマ属性用のデータ型。
+ `GlobalSecondaryIndexUpdates` – 作成するインデックスに関する詳細。
  + `IndexName` – インデックスの名前。
  + `KeySchema` – インデックスのプライマリキーに使用する属性。
  + `Projection` – テーブルからインデックスにコピーされる属性。この場合、`ALL` は、すべての属性がコピーされることを意味します。
  + `ProvisionedThroughput (for provisioned tables)` – このインデックスに必要な 1 秒あたりの読み取り/書き込み数。(これは、テーブルのプロビジョニングされたスループット設定とは異なります。) 

このオペレーションの一部は、テーブルから新しいインデックスにデータをバックフィリングすることを含みます。バックフィリング中、テーブルは使用可能なままになります。ただし、インデックスは `Backfilling` 属性が true から false に変わるまで、準備ができていません。`DescribeTable` オペレーションを使用して、この属性を表示できます。

## インデックスのクエリとスキャンをするときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.Indexes.QueryAndScan"></a>

SQL の SELECT ステートメントを使用したインデックスのクエリとスキャンを Amazon DynamoDB の `Query` および `Scan` オペレーションと比較します。

**Topics**
+ [

### SQL を使ってインデックスのクエリを実行してスキャンする
](#SQLtoNoSQL.Indexes.QueryAndScan.SQL)
+ [

### DynamoDB でインデックスのクエリを実行してスキャンする
](#SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB)

### SQL を使ってインデックスのクエリを実行してスキャンする
<a name="SQLtoNoSQL.Indexes.QueryAndScan.SQL"></a>

リレーショナルデータベースでは、インデックスを直接使用しません。代わりに、`SELECT` ステートメントの発行により、テーブルでクエリを実行し、クエリオプティマイザは任意のインデックスを利用できます。

*クエリオプティマイザ*は、使用できるインデックスを評価し、クエリを高速化するためにそれらを使用できるかを決定するリレーショナルデータベース管理システム (RDBMS) のコンポーネントです。クエリを高速化するためにインデックスが使用できる場合、RDBMS は最初にインデックスにアクセスし、それを使用してテーブルのデータを特定します。

*GenreAndPriceIndex* を使用してパフォーマンスを向上できる SQL ステートメントを次に示します。ここでは、*Music* テーブルに十分なデータがあり、クエリオプティマイザが、テーブル全体にスキャンするのではなく、このインデックスを使用することを前提にします。

```
/* All of the rock songs */

SELECT * FROM Music
WHERE Genre = 'Rock';
```

```
/* All of the cheap country songs */

SELECT Artist, SongTitle, Price FROM Music
WHERE Genre = 'Country' AND Price < 0.50;
```

### DynamoDB でインデックスのクエリを実行してスキャンする
<a name="SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB"></a>

DynamoDB では、テーブルに対して実行するのと同じように、インデックスに対して直接 `Query` および `Scan` オペレーションを実行します。DynamoDB API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、インデックスにクエリやスキャンを実行できます。`TableName` と `IndexName` の両方を指定する必要があります。

以下は、DynamoDB の *GenreAndPriceIndex* に対するいくつかのクエリです。(このインデックスのキースキーマは、*ジャンル*と*価格*で構成されています。)

------
#### [ DynamoDB API ]

```
// All of the rock songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre",
    ExpressionAttributeValues: {
        ":genre": "Rock"
    },
};
```

この例では `ProjectionExpression` を使用して、属性すべてではなく、一部のみを結果に表示することを示します。

```
// All of the cheap country songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre and Price < :price",
    ExpressionAttributeValues: {
        ":genre": "Country",
        ":price": 0.50
    },
    ProjectionExpression: "Artist, SongTitle, Price"
};
```

次に示すのは、*GenreAndPriceIndex* に対するスキャンです。

```
// Return all of the data in the index

{
    TableName:  "Music",
    IndexName: "GenreAndPriceIndex"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL では、`Select` ステートメントを使用して、インデックスに対してクエリとスキャンを実行します。

```
// All of the rock songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock'
```

```
// All of the cheap country songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock' AND Price < 0.50
```

次に示すのは、*GenreAndPriceIndex* に対するスキャンです。

```
// Return all of the data in the index

SELECT *
FROM Music.GenreAndPriceIndex
```

**注記**  
`Select` を使用したコード例については、「[DynamoDB 用の PartiQL select ステートメント](ql-reference.select.md)」を参照してください。

------

# テーブル内のデータを変更するときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.UpdateData"></a>

SQL 言語は、データを変更するための `UPDATE` ステートメントを提供します。Amazon DynamoDB は、この `UpdateItem` オペレーションを使用して同様のタスクを実行します。

**Topics**
+ [

## SQL を使用してテーブルのデータを変更する
](#SQLtoNoSQL.UpdateData.SQL)
+ [

## DynamoDB でテーブルのデータを変更する
](#SQLtoNoSQL.UpdateData.DynamoDB)

## SQL を使用してテーブルのデータを変更する
<a name="SQLtoNoSQL.UpdateData.SQL"></a>

SQL では、`UPDATE` ステートメントを使用して、1 つ以上の行を変更します。`SET` 句は、1 つ以上の行に新しい値を指定し、`WHERE` 句は変更する行を決定します。以下はその例です。

```
UPDATE Music
SET RecordLabel = 'Global Records'
WHERE Artist = 'No One You Know' AND SongTitle = 'Call Me Today';
```

`WHERE` 句に行が一致しない場合、`UPDATE` ステートメントは何も実行しません。

## DynamoDB でテーブルのデータを変更する
<a name="SQLtoNoSQL.UpdateData.DynamoDB"></a>

DynamoDB では、クラシック API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、単一の項目を変更できます。複数の項目を変更する場合は、複数のオペレーションを使用する必要があります。

------
#### [ DynamoDB API ]

DynamoDB API では、`UpdateItem` オペレーションを使用して、単一の項目を変更します。

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ExpressionAttributeValues: {
        ":label": "Global Records"
    }
}
```

属性値を指定するには、変更する項目の `Key` 属性および `UpdateExpression` を指定する必要があります。`UpdateItem` は、「アップサート」オペレーションのように動作します。テーブルに項目が存在する場合は更新され、存在しない場合は新しい項目が追加 (挿入) されます。

`UpdateItem` は、*条件付き書き込み*をサポートしており、特定の `ConditionExpression` が true と評価された場合のみ、オペレーションが成功します。たとえば、次の `UpdateItem` オペレーションは、曲の価格が 2.00 以上でない限り、更新を実行しません。

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ConditionExpression: "Price >= :p",
    ExpressionAttributeValues: {
        ":label": "Global Records",
        ":p": 2.00
    }
}
```

また、`UpdateItem` は*アトミックカウンター*、または増加減少する `Number` 型の属性をサポートしています。アトミックカウンターは多くの点で SQL データベースのシーケンスジェネレーター、IDENTITY 列、または自動インクリメントフィールドと似ています。

`UpdateItem` オペレーションを使用して、新しい属性 (*Plays*) を初期化し、曲の再生回数を追跡する例を次に示します。

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = :val",
    ExpressionAttributeValues: {
        ":val": 0
    },
    ReturnValues: "UPDATED_NEW"
}
```

`ReturnValues` パラメータは、更新された任意の属性の新しい値を返す、`UPDATED_NEW` に設定されています。この場合は、0 (ゼロ) を返します。

ユーザーがこの曲を再生するたびに、次の `UpdateItem` オペレーションを使用して *Plays* を 1 ずつ増分できます。

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = Plays + :incr",
    ExpressionAttributeValues: {
        ":incr": 1
    },
    ReturnValues: "UPDATED_NEW"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL では、`Update` ステートメントを利用する `ExecuteStatement` オペレーションを使用して、テーブル内の項目を変更します。

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。これらの属性の値を指定する必要があります。

```
UPDATE Music
SET RecordLabel ='Global Records'
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

また、次の例のように、複数のフィールドを一度に変更することもできます。

```
UPDATE Music
SET RecordLabel = 'Global Records'
SET AwardsWon = 10
WHERE Artist ='No One You Know' AND SongTitle='Call Me Today'
```

また、`Update` は*アトミックカウンター*、または増加減少する `Number` 型の属性をサポートしています。アトミックカウンターは多くの点で SQL データベースのシーケンスジェネレーター、IDENTITY 列、または自動インクリメントフィールドと似ています。

次は、曲が再生された回数を追跡するための新しい属性 (*Plays*) を初期化する `Update` ステートメントの例です。

```
UPDATE Music
SET Plays = 0
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

ユーザーがこの曲を再生するたびに、次の `Update` ステートメントを使用して *Plays* を 1 ずつ増分できます。

```
UPDATE Music
SET Plays = Plays + 1
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

**注記**  
`Update` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL 更新ステートメント](ql-reference.update.md) を参照してください。

------

# テーブルからデータを削除するときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.DeleteData"></a>

SQL では、`DELETE` ステートメントを使用してテーブルから 1 つ以上の行を削除します。Amazon DynamoDB では、この `DeleteItem` オペレーションを使用して一度に 1 つの項目を削除します。

**Topics**
+ [

## SQL を使ってテーブルからデータを削除する
](#SQLtoNoSQL.DeleteData.SQL)
+ [

## DynamoDB でテーブルからデータを削除する
](#SQLtoNoSQL.DeleteData.DynamoDB)

## SQL を使ってテーブルからデータを削除する
<a name="SQLtoNoSQL.DeleteData.SQL"></a>

SQL では、`DELETE` ステートメントを使用して、1 つ以上の行を削除します。`WHERE` 句は、変更する行を決定します。以下はその例です。

```
DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
```

`WHERE` 句を変更して、複数行を削除できます。たとえば、次の例に示すように、特定のアーティストのすべての曲を削除できます。

```
DELETE FROM Music WHERE Artist = 'The Acme Band'
```

## DynamoDB でテーブルからデータを削除する
<a name="SQLtoNoSQL.DeleteData.DynamoDB"></a>

DynamoDB では、クラシック API または [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (SQL 互換のクエリ言語) を使用して、単一の項目を削除できます。複数の項目を変更する場合は、複数のオペレーションを使用する必要があります。

------
#### [ DynamoDB API ]

DynamoDB API では、`DeleteItem` オペレーションを使用して、テーブルからデータを一度に 1 項目ずつ削除します。項目のプライマリキー値を指定する必要があります。

```
{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band",
        SongTitle: "Look Out, World"
    }
}
```

**注記**  
`DeleteItem` に加えて、Amazon DynamoDB は、同時に複数の項目を削除するための `BatchWriteItem` オペレーションをサポートしています。

`DeleteItem` は、*条件付き書き込み*をサポートしており、特定の `ConditionExpression` が true と評価された場合のみ、オペレーションが成功します。たとえば、次の `DeleteItem` オペレーションは *RecordLabel* 属性がある場合のみ項目を削除します。

```
{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band",
        SongTitle: "Look Out, World"
    },
   ConditionExpression: "attribute_exists(RecordLabel)"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL では、`ExecuteStatement` オペレーションでの `Delete`ステートメントを使用して、テーブルからデータを一度に 1 項目ずつ削除します。項目のプライマリキー値を指定する必要があります。

このテーブルのプライマリキーは、*Artist* および *SongTitle* で構成されます。これらの属性の値を指定する必要があります。

```
DELETE FROM Music
WHERE Artist = 'Acme Band' AND SongTitle = 'PartiQL Rocks'
```

オペレーションには、追加の条件を指定することもできます。次の `DELETE` オペレーションは、11 を超える *Awards* が項目に含まれる場合にのみ、その項目を削除します。

```
DELETE FROM Music
WHERE Artist = 'Acme Band' AND SongTitle = 'PartiQL Rocks' AND Awards > 11
```

**注記**  
`DELETE` と `ExecuteStatement` を使用したコード例については、[DynamoDB 用の PartiQL 削除ステートメント](ql-reference.delete.md) を参照してください。

------

# テーブルを削除するときのリレーショナル (SQL) データベースと DynamoDB の相違点
<a name="SQLtoNoSQL.RemoveTable"></a>

SQL では、`DROP TABLE` ステートメントを使用して、テーブルを削除します。Amazon DynamoDB では、`DeleteTable` オペレーションを使用します。

**Topics**
+ [

## SQL を使用してテーブルを削除する
](#SQLtoNoSQL.RemoveTable.SQL)
+ [

## DynamoDB でテーブルを削除する
](#SQLtoNoSQL.RemoveTable.DynamoDB)

## SQL を使用してテーブルを削除する
<a name="SQLtoNoSQL.RemoveTable.SQL"></a>

不要になったテーブルを完全に廃棄する場合、SQL の `DROP TABLE` ステートメントを使用します。

```
DROP TABLE Music;
```

テーブルは削除された後、復元できません。(一部のリレーショナルデータベースは `DROP TABLE` オペレーションを取消すことができますが、これはベンダー固有の機能であり、一般的には実装されていません。)

## DynamoDB でテーブルを削除する
<a name="SQLtoNoSQL.RemoveTable.DynamoDB"></a>

DynamoDB には、`DeleteTable` が同様のオペレーションです。次の例では、テーブルは完全に削除されます。

```
{
    TableName: "Music"
}
```