

# テーブルからデータを読み込むときの、リレーショナル (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) を参照してください。

------