Amazon dynamodb 如何在DynamoDB中找到按日期属性排序的实体

Amazon dynamodb 如何在DynamoDB中找到按日期属性排序的实体,amazon-dynamodb,dynamodb-queries,amazon-dynamodb-index,Amazon Dynamodb,Dynamodb Queries,Amazon Dynamodb Index,给定由id(即用户、设备等)标识的实体,该id用作表的哈希键,以及附加的日期属性(即上次修改、上次登录等)。我希望能够找到该表中最年长的条目 典型的查询是“为我找到修改日期最早的设备”或“为我找到最近登录的用户” 对于这个用例,我不知道该如何设计一个好的设计——不管是辅助表还是GSI。听起来你有一些独特的项目(用户、设备等),它们有一个可排序的时间组件(上次修改、上次登录等)。您的访问模式包括获取所有项目中最早的条目 听起来你的桌子可能看起来像这样: Users项是用一个分区键USER#定义的

给定由id(即用户、设备等)标识的实体,该id用作表的哈希键,以及附加的日期属性(即上次修改、上次登录等)。我希望能够找到该表中最年长的条目

典型的查询是“为我找到修改日期最早的设备”或“为我找到最近登录的用户”


对于这个用例,我不知道该如何设计一个好的设计——不管是辅助表还是GSI。

听起来你有一些独特的项目(用户、设备等),它们有一个可排序的时间组件(上次修改、上次登录等)。您的访问模式包括获取所有项目中最早的条目

听起来你的桌子可能看起来像这样:

Users项是用一个分区键USER#定义的,排序键是一个日期(也可以包括一天中的时间,但我已经简化了这个示例)

如果您试图跨多个分区进行搜索,则只能访问
scan
操作,这可能会使您描述的访问模式变得棘手(而且代价高昂)。让我们尝试另一种方法

让我们定义一个二级索引(GSI1),其中包含
用户的分区键(GSI1PK)和排序键(GSI1SK)作为基于时间的属性(更新时、创建时等)。该索引如下所示:

让我们从GSI1的角度来看相同的表和数据:

现在我有了一个itemcollections,它的分区键为
USERS
,还有一个日期排序键。由于要搜索的所有用户数据现在都在单个分区中,因此可以使用
query
操作在整个
USERS
分区中搜索。您可以进一步使用排序键对结果进行排序(
ScanIndexForward=False
用于降序,
ScanIndexForward=True
用于升序)。您可以在查询中设置
Limit=1
,以获取该集合中最早(或最新)的项


在DynamoDB中实现给定的访问模式通常有很多方法。我见过这种特定的模式用于实现“获取最早/最新”的访问模式。

将所有内容存储在同一分区中的代价有多大?假设我有1000万用户?在GSI1中,如果用户同时登录,会发生什么情况?索引将多次使用“用户”作为GSI1PK和相同的排序键(GSI1SK)。DynamoDB的理想用途是在分区之间均匀地分布数据。分区大小限制为10GB,因此您可以在单个分区中存储所有10M用户。但是,如果集合中的1000万项在应用程序中分布不均匀,则可能需要采用不同的策略。我演示的模式是获取按日期排序的项目的通用模式。您作为示例给出的访问模式可能会以不同的方式实现,但可以应用类似的模式。我不确定用户同时登录是什么意思。我的意思是,想象一下,在原始表中,用户将具有相同的排序键值(即user3和user4都具有2020-09-08)。这是否适用于GSI,因为两者将使用相同的索引键(“用户”,2020-09-08)?@reikje这是一个很好的问题。DynamoDB通过主表中的主键(例如分区键和可选排序键)强制唯一性。二级索引没有相同的唯一性约束。在您的示例中,这意味着您可以在主表中有多个唯一的用户,而在辅助索引中有重复的项。因此,你可以在你的二级索引中有多个项目,主键为用户,主键为2020-09-08。