【问题标题】:Query latest record for each ID in DynamoDB查询 DynamoDB 中每个 ID 的最新记录
【发布时间】:2020-07-29 14:17:48
【问题描述】:

我们有一张这样的表:

user_id | video_id | timestamp
      1          2           3
      1          3           4
      1          3           5
      2          1           1

我们需要为特定用户观看的每个视频查询最新时间戳。

目前是这样完成的:

response = self.history_table.query(
            KeyConditionExpression=Key('user_id').eq(int(user_id)),
            IndexName='WatchHistoryByTimestamp',
            ScanIndexForward=False,
        )

它查询指定用户的所有视频的所有时间戳,但它对数据库的负载确实很大,因为数千个视频可能有数千个时间戳。

我试图在互联网上找到解决方案,但我可以看到,所有 SQL 解决方案都使用 GROUP BY,但 DynamoDB 没有这样的功能

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    我知道有两种方法可以做到这一点:

    方法一 GSI 全球二级指数

    GroupBy 有点像 DynamoDB 中的分区(但不是真的)。我假设您的分区当前为user_id,但您希望video_id 作为分区键,timestamp 作为排序键。您可以创建一个新的 GSI,并指定新的排序键 timestamp 和分区键 video_id。这使您能够查询给定视频、最新时间戳,因为此查询将仅使用 1 个 RCU 并且非常快,只需添加 --max-items 1 --page-size 1。但是您需要提供video_id

    方法二稀疏索引

    1 的问题是您需要提供一个 ID,而您可能只想要一个带有最新时间戳的视频列表。有几种方法可以做到这一点,我喜欢的一种方法是使用稀疏索引,如果您有一个名为 latest 的属性并将最新的 timestamp 设置为 true,您可以创建一个 GSI 并选择它属性键latest,但不是您必须自己手动设置和取消设置此值,您必须在 lambda 流或您的应用程序中执行此操作。

    这看起来确实很奇怪,但这就是 NoSQL 的工作方式,而不是 SQL,我自己现在正在一个当前项目中与之抗争,我必须自己使用其中一些技术,每次我这样做只是没有'感觉不对,但希望我们会习惯它。

    【讨论】:

    • 哦,是的,顺便说一句,请记住,您必须在创建表时创建一个 LSI,如果您事后这样做可能会有点烦人。
    • 如何维护一个table-latest,我们将只保存最新记录并在有新记录到达时不断更新。这种方式可能不需要创建索引?除了其他字段外,主表和 latest 表都将具有键和排序键。将所有日期范围查询定向到主表;并查询 -latest 表以获取最新记录。
    • 是的,这是另一种合法的方式,这完全取决于您的用例,如果您能够对所有值进行排序,则需要一个索引,如果您想维护一个小子集,按照您在 Lambda 流中的建议可能会更好。
    猜你喜欢
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 2011-11-22
    • 2020-04-09
    • 1970-01-01
    • 2020-06-21
    相关资源
    最近更新 更多