如何在 CloudFormation 中使用基础设施即代码实施 DynamoDB 全球二级索引

How do I implement a DynamoDB Global Secondary Index with Infrastructure As Code in CloudFormation

我正在使用基础架构即代码在 CloudFormation 中实施 GSI。我想要做的就是使用这个 table 来计算主 DynamoTable 中的条目数。这是主要故事的样子:

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE

我不需要原始 table 中的密钥,我只想为新 GSI 创建一个新的 HASH 密钥,它会告诉我 table 我正在跟踪的计数of来自,即上面的table.

以下是我迄今为止尝试实施 GSI 的方式:

# Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
          - IndexName: gsiCaseCountTable
            KeySchema: 
              - AttributeName: table-name
                KeyType: HASH
            ProvisionedThroughput:
              ReadCapacityUnits: 5
              WriteCapacityUnits: 5

但是,我得到的错误如下:

An error occurred: CaseRecords - Property Projection cannot be empty..

当我包含 PROJECTION 时,只有原始 table 中的 userId 只是为了跟踪每个用户原始 table 中的条目数,我尝试以下:

 Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: table-name
          KeyType: HASH
        Projection:
          NonKeyAttributes:
          - userId
          ProjectionType: INCLUDE
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5

然而这returns也是一个错误:

An error occurred: CaseRecords - Property AttributeDefinitions is inconsistent with the KeySchema of the table and the secondary indexes.

如何使用 CloudFormation 模板在 Dynamo 中正确实施全局二级索引,以便我可以在原始 table 中记录条目数????

谢谢。

更新

如果有人想知道我是如何部署它的。这不是一个完美的解决方案,但它让我可以跟踪和计算项目 table:

的条目
# NOTE: DynamoDB Serverless Configuration
# NoSQL Table for CaseRecord DB

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
        # ReadCapacityUnits: ${self:custom.tableThroughput}
        # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: userId
          KeyType: HASH
        Projection:
          ProjectionType: KEYS_ONLY

更新 #2 - 失败

根据下面@Pedro Arantes 提供的信息,我正在尝试使用我想要使用的属性定义来实现 GSI。然而,这也是失败的。下面是实现,这是我使用的 AWS Doc 的 link:AWS GSI Doc,这是失败的实现:

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
        - AttributeName: table-name
          AttributeType: S
        - AttributeName: count
          AttributeType: N
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
        # ReadCapacityUnits: ${self:custom.tableThroughput}
        # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: table-name
          KeyType: HASH
        Projection: 
          NonKeyAttributes: 
            - userId
            - count
          ProjectionType: INCLUDE

我怎样才能让它只与我在 AttributeDefinitions 中声明的 NonKeyAttributes 一起工作???

您需要在 AttributeDefinitions 属性 处添加 table-name。来自 docs:

AttributeDefinitions

A list of attributes that describe the key schema for the table and indexes. Duplicates are allowed.

因此,即使您没有在原始 table 中使用某些属性,您也必须声明才能在您的 GSI 中使用。

更新 #2 - 失败

您正在使用您在 AttributeDefinitions 定义为 NonKeyAttributes 的键属性 userIdcount(但它们 键属性)在 Projection。您不需要添加它们,因为它们会自动投影。来自 docs:

AWS::DynamoDB::Table Projection

Represents attributes that are copied (projected) from the table into an index. These are in addition to the primary key attributes and index key attributes, which are automatically projected.

最终模板

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
        - AttributeName: table-name
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
      # ReadCapacityUnits: ${self:custom.tableThroughput}
      # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
        - IndexName: gsiCaseCountTable
          KeySchema:
            - AttributeName: table-name
              KeyType: HASH
          Projection:
            NonKeyAttributes:
              - count
            ProjectionType: INCLUDE

注意事项:

  1. count 不应在 AttributeDefinitions 上,因为您没有将其用作密钥。

  2. 您不需要在 Projection 添加 userId 因为它会自动投影,因为它是在 AttributeDefinitions.

    中定义的