Dynamo DB 关于 table 结构的建议

Dynamo DB advice on structure of table

我想像这样存储数据

{ date: '2020-10-06T20:46:01.942Z', topic: 'a great topic', votes: 123 },
{ date: '2020-10-07T23:46:01.942Z', topic: 'a great topic', votes: 125 },
{ date: '2020-10-06T20:46:03.942Z', topic: 'a not so great topic', votes: 12 }

我创建了一个 Dynamo 并将我的时间戳作为主键,由于流量低,可以安全地假设这些是唯一的。

我希望 return 基于主题的数据,以便使用等于 a great topic.

的排序键进行 dynamo 查询

在 dyanmo 数据库查询语句中使用以下内容时,我不断收到 "message": "Query condition missed key schema element"

params = {
    TableName: table,
    KeyConditionExpression: "#topic = :topic",
    ExpressionAttributeNames:{
        "#topic": "topic"
    },
    ExpressionAttributeValues: {
        ":topic": "a great topic"
    }
  }

这是我的table

var tableParams = {
    TableName : "a cool table",
    KeySchema: [       
        { AttributeName: "date", KeyType: "HASH"},  //Partition key
        {
          AttributeName: "topic",
          KeyType: "RANGE"
      }
    ],
    AttributeDefinitions: [       
        { AttributeName: "date", AttributeType: "S" },
        { AttributeName: "topic", AttributeType: "S" }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 5, 
        WriteCapacityUnits: 5
    }
};

我对使用扫描犹豫不决,因为即使使用 javascript 过滤数据会更容易,但它可能会非常浪费:p

感谢您的帮助。

如果按主题查询,将主题设置为分区(散列)键,将时间戳设置为排序(范围)键会更有效。否则,您将始终需要提供特定的时间戳,因为查询始终需要包含分区键。

一个有益的副作用是返回的结果已经按时间戳排序。

更新:详情请参考上面Seth的精彩回答!

您正在尝试使用 topic 字段查询您的 table,这将不起作用,因为它是您的排序键。查询 DynamoDB 时,需要提供分区键和可选的排序键。

让我们快速回顾一些术语,以便我们都在同一页上(来自 the docs)。

  • 主键 - 主键唯一标识 table 中的每个项目,因此任何两个项目都不能具有相同的键。 有两种不同类型的主键:
  • 分区键 – 一个简单的主键,由一个称为分区键的属性组成。
  • Partition key and sort key – 简称复合主键,这类键由两个属性组成。第一个属性是分区键,第二个属性是排序键

当您在 Dynamodb 中执行 query 操作时,您使用 KeyConditionExpression 参数为分区键提供特定值。查询操作将 return 来自 table 的所有项目或使用该分区键值编制索引。您可以选择通过在 KeyConditionExpression

中指定排序键值和比较运算符来缩小查询操作的范围

查看您的查询,您正试图通过指定 排序键来查询项目,但这是行不通的。我认为您的主键倒退了。您希望分区键为 topic,排序键为 date.

要让您的查询按书面方式工作,请将 table 的 KeySchema 更改为:

    KeySchema: [       
        { AttributeName: "topic", KeyType: "HASH"},
        { AttributeName: "date", KeyType: "RANGE"}
    ]

如果您这样做,您的 query 操作将 return 该主题的项目按日期排序。