

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 讀取資料表資料時，關聯式 (SQL) 資料庫與 DynamoDB 的主要差異
<a name="SQLtoNoSQL.ReadData"></a>

使用 SQL，您可用 `SELECT` 陳述式從資料表擷取一或多個資料列。並可用 `WHERE` 子句決定傳回給您的資料。

這與使用 Amazon DynamoDB 不同，其提供下列操作來讀取資料：
+ `ExecuteStatement` 會從資料表檢索單一或多個項目。`BatchExecuteStatement` 以單一操作從不同資料表檢索多個項目。這些操作都使用 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)，這是一種與 SQL 相容的查詢語言。
+ `GetItem`：從資料表擷取單一項目。因為可供直接存取項目的實體位置，所以此為讀取單一項目最有效率的方式。(DynamoDB 還會提供 `BatchGetItem` 操作，允許您在單一操作中執行多達 100 個 `GetItem` 呼叫。)
+ `Query`：擷取具有特定分割區索引鍵的所有項目。在那些項目中，您可以將條件套用至排序索引鍵，並只擷取部分資料。`Query` 供您快速且有效率地存取存放資料的分割區。(如需詳細資訊，請參閱 [DynamoDB 的分割區與資料分配](HowItWorks.Partitions.md)。)
+ `Scan`：擷取指定資料表中的所有項目。(此操作不應用於大型資料表，因為會使用大量系統資源)。

**注意**  
使用關聯式資料庫，您可用 `SELECT` 陳述式聯結多個資料表的資料，然後傳回結果。聯結是關聯式模型的基礎。若要確保聯結可有效率地執行，資料庫及其應用程式應持續調整其效能。DynamoDB 是不支援資料表聯結的非關聯式 NoSQL 資料庫。相反地，應用程式會一次從一個資料表讀取資料。

下列章節說明讀取資料的不同使用案例，以及如何使用關聯式資料庫和 DynamoDB 執行這些任務。

**Topics**
+ [

# 使用主索引鍵讀取項目的差異
](SQLtoNoSQL.ReadData.SingleItem.md)
+ [

# 查詢資料表的差異
](SQLtoNoSQL.ReadData.Query.md)
+ [

# 掃描資料表的差異
](SQLtoNoSQL.ReadData.Scan.md)

# 使用主索引鍵讀取項目的差異
<a name="SQLtoNoSQL.ReadData.SingleItem"></a>

資料庫常見的一種存取模式是從資料表讀取單一項目。您必須指定您想要讀取之項目的主索引鍵。

**Topics**
+ [

## 在 SQL 中使用項目的主索引鍵讀取項目
](#SQLtoNoSQL.ReadData.SingleItem.SQL)
+ [

## 在 DynamoDB 中使用項目的主索引鍵讀取項目
](#SQLtoNoSQL.ReadData.SingleItem.DynamoDB)

## 在 SQL 中使用項目的主索引鍵讀取項目
<a name="SQLtoNoSQL.ReadData.SingleItem.SQL"></a>

在 SQL 中，您會使用 `SELECT` 陳述式從資料表擷取資料。您可以在結果中請求一或多個資料行 (或使用 `*` 運算子請求所有資料行)。`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 使用其 `Query` 和 `Scan` 操作提供類似功能，這些操作會在 [查詢資料表的差異](SQLtoNoSQL.ReadData.Query.md) 和 [掃描資料表的差異](SQLtoNoSQL.ReadData.Scan.md) 中說明。

SQL `SELECT` 陳述式可執行資料表聯結，可讓您同時從多個資料表擷取資料。在資料庫資料表標準化且資料表間的關聯性明確時，聯結最為有效。但是，若您在單一 `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 Select 陳述式也可以用來查詢或掃描 DynamoDB 資料表

如需使用 `Select` 和 `ExecuteStatement` 的程式碼範例，請參閱 [適用於 DynamoDB 的 PartiQL Select 陳述式](ql-reference.select.md)。

------

# 查詢資料表的差異
<a name="SQLtoNoSQL.ReadData.Query"></a>

資料庫常見的另一種存取模式是根據您的查詢條件，從資料表讀取多個項目。

**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 中，您必須使用 `ExpressionAttributeValues` 作為表達式參數 (例如 `KeyConditionExpression` 及 `FilterExpression`) 中的預留位置。這與在關聯式資料庫中使用*繫結變數*類似，您會在執行時期將實際值代入 `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 時，您可以使用不指定 `WHERE` 子句的 `SELECT` 陳述式來掃描資料表，並擷取其中的所有資料。您可以在結果中請求一或多個資料行。或者，您可以使用萬用字元 (\$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，可使用 `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，您可以藉由使用 `ExecuteStatement` 操作並使用 `Select` 陳述式傳回資料表的所有內容。

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

請注意，此陳述式會傳回「Music」資料表中的所有項目。

如需使用 `Select` 和 `ExecuteStatement` 的程式碼範例，請參閱 [適用於 DynamoDB 的 PartiQL Select 陳述式](ql-reference.select.md)。

------