

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

# Amazon DynamoDB 的核心元件
<a name="HowItWorks.CoreComponents"></a>

在 DynamoDB 中，資料表、項目與屬性都是您會用到的核心元件。*資料表*是*項目*的集合，而每個項目則是*屬性*的集合。DynamoDB 使用主索引鍵來唯一識別資料表中的每個項目。您可以使用 DynamoDB Streams 來擷取 DynamoDB 資料表中的資料修改事件。

 DynamoDB 中有其限制。如需詳細資訊，請參閱[Amazon DynamoDB 中的配額](ServiceQuotas.md)。

以下影片將為您介紹資料表、項目與屬性。

[資料表、項目與屬性](https://www.youtube.com/embed/Mw8wCj0gkRc)

## 資料表、項目與屬性
<a name="HowItWorks.CoreComponents.TablesItemsAttributes"></a>

![\[每個 DynamoDB 資料表可包含零個或多個項目，每個項目由一個或多個屬性組成。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/HowItWorksTables-2024.png)


以下是基本 DynamoDB 元件：
+ **資料表**：與其他資料庫系統類似，DynamoDB 會將資料存放在資料表中。*資料表*是資料的集合。例如，您可以使用名為 *People* 的資料表範例，來存放朋友、家人或其他任何人的相關個人聯絡資訊。您也可以使用 *Cars* 資料表來存放各人駕駛之車輛的相關資訊。
+ **項目**：每個資料表包含零或多個項目。*項目*是可從所有其他項目唯一識別的一組屬性。在 *People* 資料表中，每個項目代表一個人。在 *Cars* 資料表中，每個項目代表一輛車。DynamoDB 中的項目與其他資料庫系統中的資料列、紀錄或元組有許多相似之處。在 DynamoDB 中，可以存放在資料表中的項目數不限。
+ **屬性**：每個項目是由一或多個屬性所組成。*屬性*是一種基本資料元素，不必再進一步細分。例如，*People* 資料表中的項目包含名為 *PersonID*、*LastName*、*FirstName* 等屬性。在 *Department* 資料表中，項目可能會有 *DepartmentID*、*Name*、*Manager* 等屬性。DynamoDB 中的屬性與其他資料庫系統中的欄位或資料行有許多相似之處。

下圖顯示一個名為 *People* 的資料表，其中包含一些範例項目與屬性。

```
People

{
    "PersonID": 101,
    "LastName": "Smith",
    "FirstName": "Fred",
    "Phone": "555-4321"
}

{
    "PersonID": 102,
    "LastName": "Jones",
    "FirstName": "Mary",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}

{
    "PersonID": 103,
    "LastName": "Stephens",
    "FirstName": "Howard",
    "Address": {
                "Street": "123 Main",
                "City": "London",                                    
                "PostalCode": "ER3 5K8"
    },
    "FavoriteColor": "Blue"
}
```

*People* 資料表的注意事項如下：
+ 資料表中的每個項目都有唯一識別符或主索引鍵，可區分該項目與資料表中的所有其他項目。在 *People* 資料表中，主索引鍵是由一個屬性 (*PersonID*) 所組成。
+ 除了主索引鍵之外，*People* 資料表沒有結構描述，這表示您不需要事先定義屬性或其資料類型。每個項目可以有其專屬的不同屬性。
+ 大多數屬性為*純量*，亦即只能有一個值。字串與數字是常見的純量範例。
+ 有些項目有巢狀屬性 (*Address*)。DynamoDB 支援巢狀屬性，最多 32 層深。

以下是另一個名為 *Music* 的範例資料表，您可以用來追蹤音樂收藏。

```
Music

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

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

{
    "Artist": "The Acme Band",
    "SongTitle": "Still in Love",
    "AlbumTitle": "The Buck Starts Here",
    "Price": 2.47,
    "Genre": "Rock",
    "PromotionInfo": {
        "RadioStationsPlaying": [
            "KHCR",
            "KQBX",
            "WTNR",
            "WJJH"
        ],
        "TourDates": {
            "Seattle": "20150622",
            "Cleveland": "20150630"
        },
        "Rotation": "Heavy"
    }
}

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

*Music* 資料表的注意事項如下：
+ *Music* 的主索引鍵是由兩個屬性 (*Artist* 與 *SongTitle*) 所組成。資料表中的每個項目必須有這兩個屬性。*Artist* 與 *SongTitle* 的組合可區分資料表中的每個項目與所有其他項目。
+ 除了主索引鍵之外，*Music* 資料表沒有結構描述，這表示您不需要事先定義屬性或其資料類型。每個項目可以有其專屬的不同屬性。
+ 其中一個項目有巢狀屬性 (*PromotionInfo*)，包含其他的巢狀屬性。DynamoDB 支援巢狀屬性，最多 32 層深。

 如需詳細資訊，請參閱 [在 DynamoDB 中使用資料表和資料](WorkingWithTables.md)。

## 主索引鍵
<a name="HowItWorks.CoreComponents.PrimaryKey"></a>

當您建立資料表時，除了資料表名稱，您還必須指定資料表的主索引鍵。主索引鍵可唯一識別資料表中的每個項目，因此兩個項目不能具有相同的索引鍵。

DynamoDB 支援兩種不同類型的主索引鍵：
+ **分割區索引鍵**：簡易主索引鍵，由一個屬性 (稱為*分割區索引鍵*) 所組成。

  DynamoDB 使用分割區索引鍵值作為內部雜湊函數的輸入。雜湊函數的輸出決定要存放項目的分割區 (DynamoDB 的內部實體儲存體)。

   在只有一個分割區索引鍵的資料表中，沒有兩個項目的分割區索引鍵值是相同的。

  所以 [資料表、項目與屬性](#HowItWorks.CoreComponents.TablesItemsAttributes) 中描述的 *People* 資料表，是具有簡單主索引鍵 (*PersonID*) 的資料表範例。您可以藉由提供 *People* 資料表中任何項目的 *PersonId* 值，來直接存取該項目。
+ **分割區索引鍵與排序索引鍵**：稱為*複合主鍵*，這種類型的索引鍵是由兩個屬性組成。第一個屬性是*分割區索引鍵*，第二個屬性是*排序索引鍵*。

  DynamoDB 使用分割區索引鍵值作為內部雜湊函數的輸入。雜湊函數的輸出決定要存放項目的分割區 (DynamoDB 的內部實體儲存體)。具有相同分割區索引鍵值的所有項目會存放在一起，並依排序索引鍵值排序。

  在具有一個分割區金鑰與一個排序索引鍵的資料表中，兩個項目可能會有相同的分割區索引鍵值。不過，這兩個項目必須具有不同的排序索引鍵值。

  [資料表、項目與屬性](#HowItWorks.CoreComponents.TablesItemsAttributes) 中描述的 *Music* 資料表，是具有複合主鍵 (*Artist* 和 *SongTitle*) 的資料表範例。如果您提供 *Music* 資料表中任何項目的 *Artist* 與 *SongTitle* 值，即可直接存取該項目。

  複合主鍵可讓您更有彈性地查詢資料。例如，如果您只提供 *Artist* 值，則 DynamoDB 會擷取該演出者的所有歌曲。您可以提供一個 *Artist* 值與一段範圍的 *SongTitle* 值，來擷取特定演出者的歌曲子集。

**注意**  
項目的分割區索引鍵也稱為其*雜湊屬性*。*雜湊屬性*一詞衍生自 DynamoDB 中內部雜湊函數的用法，可將資料項目根據其分割區索引鍵值平均分佈到所有分割區。  
項目的排序索引鍵也稱為其*範圍屬性*。*範圍屬性*一詞衍生自 DynamoDB 存放項目的方式，具有相同分割區索引鍵的項目會實際緊密相鄰，並依排序索引鍵值排序。

每個主索引鍵屬性必須是純量 (亦即只能保留一個值)。主索引鍵屬性允許的資料類型僅限於字串、數字或二進位。其他非索引鍵屬性則沒有此限制。

## 次要索引
<a name="HowItWorks.CoreComponents.SecondaryIndexes"></a>

您可以在資料表上建立一或多個次要索引。*次要索引*可讓您在除了使用主索引鍵查詢外，也可使用備用索引鍵查詢資料表中的資料。DynamoDB 不需要您使用索引，但可讓您的應用程式在查詢資料時更具靈活性。在資料表上建立次要索引之後，您可以從索引讀取資料，方法與從資料表讀取十分相似。

DynamoDB 支援兩種索引：
+ 全域次要索引：一種含分割區索引鍵或排序索引鍵的索引，這些索引鍵可與資料表上的索引鍵不同。在全域次要索引中，主索引鍵值無需唯一。
+ 本機次要索引：是一種與資料表擁有相同分割區索引鍵但不同排序索引鍵的索引。

在 DynamoDB 中，全域次要索引 (GSI) 是涵蓋整個資料表的索引，可讓您查詢所有分割區索引鍵。本機次要索引 (LSI) 是一種與基礎資料表共用相同分割區索引鍵，但具有不同排序索引鍵的索引。

DynamoDB 中的每個資料表配額為 20 個全域次要索引 (預設配額) 與 5 個本機次要索引。

在上述範例 *Music* 資料表中，您可以依 *Artist* (分割區索引鍵) 或依 *Artist* 與 *SongTitle* (分割區索引鍵與排序索引鍵) 查詢資料項目。如果您也想要依 *Genre* 與 *AlbumTitle* 查詢資料，該怎麼辦？ 若要執行此作業，您可以在 *Genre* 與 *AlbumTitle* 上建立索引，然後查詢索引，方法與查詢 *Music* 資料表十分相似。

下圖顯示 *Music* 資料表範例，其中包含一個名為 *GenreAlbumTitle* 的新索引。在此索引中，*Genre* 是分割區索引鍵，而 *AlbumTitle* 是排序索引鍵。


| 音樂資料表 | *GenreAlbumTitle* | 
| --- | --- | 
|  <pre><br />{<br />    "Artist": "No One You Know",<br />    "SongTitle": "My Dog Spot",<br />    "AlbumTitle": "Hey Now",<br />    "Price": 1.98,<br />    "Genre": "Country",<br />    "CriticRating": 8.4<br />}                               <br />                                </pre>  |  <pre><br />{<br />    "Genre": "Country",<br />    "AlbumTitle": "Hey Now",<br />    "Artist": "No One You Know",<br />    "SongTitle": "My Dog Spot"<br />}<br />                                </pre>  | 
|  <pre><br />{<br />    "Artist": "No One You Know",<br />    "SongTitle": "Somewhere Down The Road",<br />    "AlbumTitle": "Somewhat Famous",<br />    "Genre": "Country",<br />    "CriticRating": 8.4,<br />    "Year": 1984<br />}<br />                                </pre>  |  <pre><br />{<br />    "Genre": "Country",<br />    "AlbumTitle": "Somewhat Famous",<br />    "Artist": "No One You Know",<br />    "SongTitle": "Somewhere Down The Road"<br />}<br />                                </pre>  | 
|  <pre><br />{<br />    "Artist": "The Acme Band",<br />    "SongTitle": "Still in Love",<br />    "AlbumTitle": "The Buck Starts Here",<br />    "Price": 2.47,<br />    "Genre": "Rock",<br />    "PromotionInfo": {<br />        "RadioStationsPlaying": {<br />            "KHCR",<br />            "KQBX",<br />            "WTNR",<br />            "WJJH"<br />        },<br />        "TourDates": {<br />            "Seattle": "20150622",<br />            "Cleveland": "20150630"<br />        },<br />        "Rotation": "Heavy"<br />    }<br />}<br />                                </pre>  |  <pre><br />{<br />    "Genre": "Rock",<br />    "AlbumTitle": "The Buck Starts Here",<br />    "Artist": "The Acme Band",<br />    "SongTitle": "Still In Love"<br />}<br />                                </pre>  | 
|  <pre><br />{<br />    "Artist": "The Acme Band",<br />    "SongTitle": "Look Out, World",<br />    "AlbumTitle": "The Buck Starts Here",<br />    "Price": 0.99,<br />    "Genre": "Rock"<br />}<br />                                </pre>  |  <pre><br />{<br />    "Genre": "Rock",<br />    "AlbumTitle": "The Buck Starts Here",<br />    "Artist": "The Acme Band",<br />    "SongTitle": "Look Out, World"<br />}<br />                                </pre>  | 

*GenreAlbumTitle* 索引的注意事項如下：
+ 每個索引都屬於一個資料表，稱為索引的*基礎資料表*。在上述範例中，*Music* 是 *GenreAlbumTitle* 索引的基礎資料表。
+ DynamoDB 會自動維護索引。當您新增、更新或刪除基礎資料表中的項目時，DynamoDB 會在屬於該資料表的任何索引中新增、更新或刪除對應的項目。
+ 建立索引時，您可以指定要從基礎資料表複製或*投影*到索引的屬性。DynamoDB 至少會將索引鍵屬性從基礎資料表投影到索引。`GenreAlbumTitle` 即為一例，其中只有索引鍵屬性會從 `Music` 資料表投影到索引。

您可以查詢 *GenreAlbumTitle* 索引，尋找特定內容類型的所有專輯 (例如所有 *Rock* 專輯)。您也可以查詢此索引，尋找特定內容類型中具有特定專輯標題的所有專輯 (例如標題開頭字母為 H 的所有 *Country* 專輯)。

如需詳細資訊，請參閱 [在 DynamoDB 中使用次要索引來改善資料存取](SecondaryIndexes.md)。

## DynamoDB Streams
<a name="HowItWorks.CoreComponents.Streams"></a>

DynamoDB Streams 是選用功能，可擷取 DynamoDB 資料表中的資料修改事件。這些事件的相關資料會依事件出現的順序，近乎即時地出現在串流中。

每個事件是以*串流紀錄*表示。如果您在資料表上啟用串流，只要發生下列其中一個事件，DynamoDB Streams 就會寫入一個串流紀錄：
+ 新增項目至資料表：串流會擷取整個項目的影像，包括其所有屬性。
+ 項目已更新：串流會擷取項目中已修改之任何屬性的「之前」與「之後」影像。
+ 從資料表刪除項目：串流會擷取整個項目的影像，再加以刪除。

每個串流紀錄也會包含資料表的名稱、事件時間戳記與其他中繼資料。串流紀錄的存留期為 24 小時，之後會自動從串流移除。

您可以將 DynamoDB Streams 與 搭配使用 AWS Lambda 來建立*觸發*，只要串流中出現感興趣的事件，就會自動執行程式碼。例如，以含有公司客戶資訊的 *Customers* 資料表為例。假設您想要傳送「歡迎」電子郵件給每個新客戶。您可以在該資料表上啟用串流，然後將串流與 Lambda 函式建立關聯。Lambda 函式會在每次出現新的串流紀錄時執行，但只會處理 *Customers* 資料表的新增項目。針對具有 `EmailAddress` 屬性的任何項目，Lambda 函式會調用 Amazon Simple Email Service (Amazon SES) 來將電子郵件傳送至該地址。

![\[將 DynamoDB Streams 與 Lambda 整合，以自動傳送歡迎電子郵件給新客戶。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/HowItWorksStreams.png)


**注意**  
在此範例中，最後一個客戶 Craig Roe 不會收到電子郵件，因為他沒有 `EmailAddress`。

除了觸發之外，DynamoDB Streams 還支援強大的解決方案，例如區域內和跨 AWS 區域的資料複寫、DynamoDB 資料表中資料的具體化視觀表、使用 Kinesis 具體化視觀表的資料分析等等。

如需詳細資訊，請參閱[DynamoDB Streams 的變更資料擷取](Streams.md)。