

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

# 階層式資料建模的範例
<a name="hierarchical-data-modeling"></a>

下列各節使用汽車公司範例，示範如何使用資料建模程序步驟在 DynamoDB 中設計多層元件管理系統。

**Topics**
+ [步驟 1：識別使用案例和邏輯資料模型](step1-hierarchical-model.md)
+ [步驟 2：建立初步成本估算](step2-hierarchical-model.md)
+ [步驟 3：識別您的資料存取模式](step3-hierarchical-model.md)
+ [步驟 4：識別技術需求](step4-hierarchical-model.md)
+ [步驟 5：建立 DynamoDB 資料模型](step5-hierarchical-model.md)
+ [步驟 6：建立資料查詢](step6-hierarchical-model.md)
+ [步驟 7：驗證資料模型](step7-hierarchical-model.md)
+ [步驟 8：檢閱成本估算](step8-hierarchical-model.md)
+ [步驟 9：部署資料模型](step9-hierarchical-model.md)

# 步驟 1：識別使用案例和邏輯資料模型
<a name="step1-hierarchical-model"></a>

一家汽車公司想要建置交易元件管理系統，以存放和搜尋所有可用的汽車零件，並在不同的元件和零件之間建立關係。例如，一輛汽車包含多顆電池，每顆電池包含多個高層級模組，每個模組包含多個電芯，每個電芯包含多個低階元件。

一般來說，為了建置階層關係模型，[Amazon Neptune](https://docs.aws.amazon.com/neptune/latest/userguide/intro.html) 等圖形資料庫是更好的選擇。不過，在某些情況下，Amazon DynamoDB 因為其彈性、安全性、效能和規模，是階層式資料建模的更佳替代方案。

例如，您可能會建置一個系統，其中 80-90% 的查詢是交易，DynamoDB 非常適合該系統。在此範例中，其他 10–20% 的查詢是關聯式查詢，其中 Neptune 等圖形資料庫更適合。在這種情況下，在架構中包含額外的資料庫，只滿足 10-20% 的查詢可能會增加成本。它還增加了維護多個系統和同步資料的操作負擔。相反，您可以在 DynamoDB 中對該 10-20% 的關聯式查詢建模。

繪製汽車元件的範例樹狀目錄可以協助您映射它們之間的關係。下列圖表顯示具有四個層級的相依性圖形。CM1 是範例汽車本身的頂層元件。它具有兩個子元件，用於兩個範例電池即 CM2 和 CM3。每個電池都具有兩個子元件，即模組。CM2 具有模組 CM4 和 CM5，而 CM3 具有模組 CM6 和 CM7。每個模組都具有幾個子元件，即電芯。CM4 模組具有兩個電芯，即 CM8 和 CM9。CM5 具有一個電芯即 CM10。CM6 和 CM7 還沒有任何關聯的電芯。



![\[顯示先前描述的關係的範例樹狀目錄圖。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/images/example-tree.png)


本指南將使用此樹狀目錄及其元件識別符作為參考。頂端元件將稱為*父項*，子元件將稱為*子項***。**例如，頂端元件 CM1 是 CM2 和 CM3 的父項。CM2 是 CM4 和 CM5 的父項。這描繪了父項和子項關係。

從樹狀目錄中，您可以看到元件的完整相依性圖形。例如，CM8 依賴於 CM4，CM4 依賴於 CM2，CM2 依賴於 CM1。此樹狀目錄將完整的相依性圖形定義為路徑。路徑描述了以下兩個項目：
+ 相依性圖形
+ 樹狀目錄中的位置

填寫範本以滿足業務需求：

提供使用者的相關資訊：


|  |  | 
| --- |--- |
| **使用者** | **Description** | 
| 員工 | 需要汽車及其元件資訊之汽車公司的內部員工 | 

提供資料來源以及如何擷取資料的相關資訊：


|  |  |  | 
| --- |--- |--- |
| **來源** | **Description** | **使用者** | 
| 管理系統 | 系統將存放與可用汽車零件相關的所有資料，以及它們與其他元件和零件的關係。 | 員工 | 

提供如何使用資料的相關資訊：


|  |  |  | 
| --- |--- |--- |
| **消費者** | **Description** | **使用者** | 
| 管理系統 | 擷取父元件 ID 的所有立即子元件。 | 員工 | 
| 管理系統 | 擷取元件 ID 的所有子元件的遞迴清單。 | 員工 | 
| 管理系統 | 請參閱元件的祖先。 | 員工 | 

# 步驟 2：建立初步成本估算
<a name="step2-hierarchical-model"></a>

請務必計算應用程式所有環境的成本估算，以便檢查解決方案在財務上是否可行。最佳實務是進行高階估算，並在繼續進行開發和部署之前取得業務分析師的核准。
+ 資料庫工程師會使用可用資訊和 [DynamoDB 定價頁面上](https://aws.amazon.com/dynamodb/pricing/)顯示的範例來建立初始成本分析。
  + 建立隨需容量的成本預估 （請參閱[範例](https://aws.amazon.com/dynamodb/pricing/on-demand/))。
  + 建立佈建容量的成本預估 （請參閱[範例](https://aws.amazon.com/dynamodb/pricing/provisioned/))。
    + 對於佈建容量模型，請從計算器取得預估成本，並套用預留容量的折扣。
  + 比較兩個容量模型的預估成本。
  + 為所有環境 (Dev、Prod、QA) 建立估算。
+ 商業分析師會檢閱和核准或拒絕初步成本估算。

使用這些參考值，您可以建立要提交以供核准的預估價格。若要建立預算，您可以使用 [DynamoDB 定價頁面](https://aws.amazon.com/dynamodb/pricing/) 和 [AWS 定價計算工具](https://calculator.aws/)。

# 步驟 3：識別您的資料存取模式
<a name="step3-hierarchical-model"></a>

此範例使用案例具有下列存取模式，用於管理不同汽車元件之間的關係。


|  |  |  |  |  |  |  | 
| --- |--- |--- |--- |--- |--- |--- |
| **存取模式** | **優先順序** | **讀取或寫入** | **Description (描述)** | **類型** | **篩選條件** | **結果排序** | 
| 直屬子系 | 高 | 讀取 | 擷取父元件 ID 的所有立即子元件。 | 多個 | `ComponentID` | N/A | 
| 所有子元件 | 高 | 讀取 | 擷取元件 ID 的所有子元件的遞迴清單。 | 多個 | `ComponentID` | N/A | 
| Ancestors | 高 | 讀取 | 擷取元件的祖先。 | 多個 | `ComponentID` | N/A | 

# 步驟 4：識別技術需求
<a name="step4-hierarchical-model"></a>

此範例沒有任何特定的技術需求，這些需求超出此範例的範圍。在實際情況下，最佳實務是完成此步驟，並在繼續進行開發和部署之前驗證是否滿足所有技術要求。您可以使用[範例問卷](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-data-modeling/template-tech-req.html)，在商業案例中完成此步驟。此外，我們建議驗證 [DynamoDB 服務配額](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ServiceQuotas.html)，以確保您設計的解決方案沒有硬性限制。

# 步驟 5：建立 DynamoDB 資料模型
<a name="step5-hierarchical-model"></a>

定義基底資料表和全域次要索引 (GSIs分割區索引鍵：
+ 遵循金鑰設計最佳實務，在此範例中使用 `ComponentId`作為基底資料表的分割區索引鍵。因為它是唯一的， `ComponentId` 可以提供精細程度。DynamoDB 使用分割區索引鍵的雜湊值來決定實際儲存資料的分割區。唯一元件 ID 會產生不同的雜湊值，可加速分佈資料表內的資料。您可以使用`ComponentId`分割區索引鍵查詢基底資料表。
+ 若要尋找元件的直接子項，請建立 GSI，其中 `ParentId` 是分割區索引鍵，而 `ComponentId`是排序索引鍵。您可以使用 `ParentId`做為分割區索引鍵來查詢此 GSI。
+ 若要尋找元件的所有遞迴子項，請建立 GSI，其中 `GraphId` 是分割區索引鍵，`Path` 是排序索引鍵。您可以使用 `GraphId` 作為分割區索引鍵並在排序索引鍵上使用 `BEGINS_WITH(Path, "$path")` 運算子來查詢此 GSI。


|  |  |  |  | 
| --- |--- |--- |--- |
|  | **分割區索引鍵** | **排序索引鍵** | **映射屬性** | 
| **基礎資料表** | `ComponentId` |  | `ParentId`, `GraphId`, `Path` | 
| **GSI1** | `ParentId` | `ComponentId` |  | 
| **GSI2** | `GraphId` | `Path` | `ComponentId` | 

## 將元件儲存在資料表中
<a name="store"></a>

下一步是將每個元件儲存在 DynamoDB 基本資料表中。從範例樹狀結構插入所有元件後，您會取得下列基礎資料表。


|  |  |  |  | 
| --- |--- |--- |--- |
| **ComponentId** | **ParentId** | **GraphId** | **路徑** | 
|  CM1 |  |  CM1\$11 |  CM1 | 
|  CM2 |  CM1 |  CM1\$11 |  CM1\$1CM2 | 
|  CM3 |  CM1 |  CM1\$11 |  CM1\$1CM3 | 
|  CM4 |  CM2 |  CM1\$11 |  CM1\$1CM2\$1CM4 | 
|  CM5 |  CM2 |  CM1\$11 |  CM1\$1CM2\$1CM5 | 
|  CM6 |  CM3 |  CM1\$11 |  CM1\$1CM3\$1CM6 | 
|  CM7 |  CM3 |  CM1\$11 |  CM1\$1CM3\$1CM7 | 
|  CM8 |  CM4 |  CM1\$11 |  CM1\$1CM2\$1CM4\$1CM8 | 
|  CM9 |  CM4 |  CM1\$11 |  CM1\$1CM2\$1CM4\$1CM9 | 
|  CM10 |  CM5 |  CM1\$11 |  CM1\$1CM2\$1CM5\$1CM10 | 

## GSI1 索引
<a name="gsi1-index"></a>

若要檢查元件的所有直屬子項，您可以建立索引，使用 `ParentId`做為分割區索引鍵和`ComponentId`排序索引鍵。下列樞紐分析表呈現 GSI1 索引。您可以使用此索引透過父元件 ID 擷取所有直屬子系元件。例如，您可以了解汽車 (CM1) 中有多少顆可用電池，或模組 (CM4) 中有哪些電芯可用。


|  |  | 
| --- |--- |
| **ParentId** | **ComponentId** | 
| CM1 | CM2CM3 | 
| CM2 | CM4CM5 | 
| CM3 | CM6CM7 | 
| CM4 | CM8CM9 | 
| CM5 | CM10 | 

## GSI2 索引
<a name="gsi2-index"></a>

下列樞紐分析表呈現 GSI2 索引。它使用 `GraphId` 作為分割區索引鍵和使用 `Path` 作為排序索引鍵進行設定。在排序索引鍵 (`Path`) 上使用 `GraphI`d 和 `begins_with`操作，您可以在樹狀目錄中找到元件的完整系列。


|  |  |  | 
| --- |--- |--- |
| **GraphId** | **路徑** | **ComponentId** | 
| CM1\$11 | CM1CM1\$1CM2CM1\$1CM3CM1\$1CM2\$1CM4CM1\$1CM2\$1CM5CM1\$1CM2\$1CM4\$1CM8CM1\$1CM2\$1CM4\$1CM9CM1\$1CM2\$1CM5\$1CM10CM1\$1CM3\$1CM6CM1\$1CM3\$1CM7 | CM1CM2CM3CM4CM5CM8CM9CM10CM6CM7 | 

# 步驟 6：建立資料查詢
<a name="step6-hierarchical-model"></a>

定義存取模式並設計資料模型後，您可以在 DynamoDB 資料庫中查詢階層資料。做為節省成本並協助確保效能的最佳實務，下列範例僅使用不含 的查詢操作`Scan`。
+ **尋找元件的上階。**

  若要尋找 CM8 元件的上階 (父、祖父、曾祖父等)，請使用 `ComponentId = "CM8"` 查詢基本資料表。此查詢會傳回下列記錄。

  若要減少結果資料的大小，您可以使用投射表達式以僅傳回 `Path` 屬性。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)
+ **尋找元件的直屬子系。**

  若要取得 CM2 元件的所有直接子項或單一層級下游元件，請使用 查詢 GSI1`ParentId = "CM2"`。此查詢會傳回下列記錄。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)
+ **使用頂層元件尋找所有下游子元件。**

  若要取得頂層元件 CM1 的所有子元件或下游元件，請使用 `GraphId = "CM1#1"`和 查詢 GSI2`begins_with("Path", "CM1|")`，並使用投影表達式搭配 `ComponentId`。它將傳回與該樹狀目錄相關的所有元件。

  此範例具有單一樹狀目錄，其中 CM1 為頂端元件。實際上，您在相同表格中可能具有數百萬個頂層元件。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)
+ **使用中階元件尋找所有下游子元件。**

  若要以遞迴方式取得元件 CM2 的所有子元件或下游元件，您有兩個選項。您可以用遞迴方式逐層查詢，也可以查詢 GSI2 索引。
  + 以遞迴方式逐層查詢 GSI1，直到到達最後一層子元件。

    1. 使用 `ParentId = "CM2"` 查詢 GSI1。它將傳回下列記錄。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)

    1. 再次使用 `ParentId = "CM4"` 查詢 GSI1。它將傳回下列記錄。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)

    1. 再次使用 `ParentId = "CM5"` 查詢 GSI1。它將傳回下列記錄。

       繼續循環：查詢每個 `ComponentId`，直到到達最後一層。使用 `ParentId = "<ComponentId>"` 的查詢未傳回任何結果時，先前的結果來自樹狀目錄的最後一層。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)

    1. 合併所有結果。

        

       result=【CM4， CM5】 \$1 【CM8， CM9】 \$1 【CM10】

                =【CM4、CM5, CM8, CM9, CM10】
  + 查詢 GSI2，它儲存頂層元件 (汽車或 CM1) 的階層樹狀目錄。

    1. 首先，尋找頂層元件或頂級上階和 CM2 的 `Path`。為此，使用 `ComponentId = "CM2"` 查詢基本資料表，以尋找階層樹狀目錄中該元件的路徑。選取 `GraphId`和 `Pat`h 屬性。此查詢會傳回下列記錄。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)

    1. 使用 查詢 GSI2`GraphId = "CM1#1" AND BEGINS_WITH("Path", "CM1|CM2|")`。此查詢會傳回下列結果。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/dynamodb-data-modeling/step6-hierarchical-model.html)

    1. 選取 `ComponentId` 屬性，以傳回 CM2 的所有子元件。

# 步驟 7：驗證資料模型
<a name="step7-hierarchical-model"></a>

在此步驟中，商業使用者會驗證查詢結果，並檢查是否符合業務需求。您可以使用下表，根據使用者的需求檢查存取模式。


|  |  |  | 
| --- |--- |--- |
| **問題** | **基礎資料表/GSI** | **Query** | 
| 作為使用者，我想要擷取父元件 ID 的所有直屬子元件。 | GSI1 | `ParentId = "<ComponentId>"`(尋找元件的直屬子系。) | 
| 作為使用者，我想要擷取元件 ID 的所有子元件的遞迴清單。 | GSI1 或 GSI2 | GSI1：`ParentId = "<ComponentId>"`或GSI2：`GraphId = "<TopLevelComponentId>#N" AND BEGINS_WITH("Path", "<PATH_OF_Component>")`(使用頂層元件尋找所有下層子元件。使用中層元件尋找所有下層子元件。) | 
| 作為使用者，我想要查看元件的上階。 | 基本資料表 | `ComponentId = "<ComponentId>"`，然後選取路徑屬性。(尋找元件的上階。) | 

您也可以在任何程式設計語言中實作指令碼 （測試），以直接查詢 DynamoDB，並將結果與預期結果進行比較。

# 步驟 8：檢閱成本估算
<a name="step8-hierarchical-model"></a>

再次檢閱和精簡成本估算。此外，與業務利益相關者進行驗證並取得核准以進入下一個步驟是很好的做法。



## 目標
<a name="obj8-hierarchical-model"></a>
+ 定義容量模型，並預估 DynamoDB 成本，以精簡[步驟 2 ](step2-hierarchical-model.md)的成本估算。
+ 取得業務分析師和利益相關者的最終財務核准。

## 流程
<a name="proc8-hierarchical-model"></a>
+ 資料庫工程師會識別資料磁碟區預估。
+ 資料庫工程師會識別資料傳輸需求。
+ 資料庫工程師會定義所需的讀取和寫入容量單位。
+ 商業分析師會決定[隨需和佈建容量模型](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html)。
+ 資料庫工程師會識別 [DynamoDB 自動擴展](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AutoScaling.html)的需求。
+ 資料庫工程師會在 中輸入參數 AWS 定價計算工具。
+ 資料庫工程師向業務利益相關者提供最終價格估算。
+ 商業分析師和利益相關者核准或拒絕解決方案。

# 步驟 9：部署資料模型
<a name="step9-hierarchical-model"></a>

在此特定範例中，模型的部署是使用 [NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) 完成，這是用於現代資料庫開發和操作的應用程式。使用此工具，您可以選擇建立資料模型、上傳資料，以及將其直接部署到您的 AWS 帳戶。如果您想要實作此範例，您可以使用下列由 NoSQL Workbench 產生的 AWS CloudFormation 範本。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Components:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      KeySchema:
        - AttributeName: ComponentId
          KeyType: HASH
      AttributeDefinitions:
        - AttributeName: ComponentId
          AttributeType: S
        - AttributeName: ParentId
          AttributeType: S
        - AttributeName: GraphId
          AttributeType: S
        - AttributeName: Path
          AttributeType: S
      GlobalSecondaryIndexes:
        - IndexName: GS1
          KeySchema:
            - AttributeName: ParentId
              KeyType: HASH
            - AttributeName: ComponentId
              KeyType: RANGE
          Projection:
            ProjectionType: KEYS_ONLY
        - IndexName: GSI2
          KeySchema:
            - AttributeName: GraphId
              KeyType: HASH
            - AttributeName: Path
              KeyType: RANGE
          Projection:
            ProjectionType: INCLUDE
            NonKeyAttributes:
              - ComponentId
      BillingMode: PAY_PER_REQUEST
      TableName: Components
```