我正在开发一个允许用户阅读书籍的应用程序 . 我使用DynamoDB存储用户阅读的书籍的详细信息,我计划使用DynamoDB中存储的数据来计算统计数据,例如趋势书籍,作者等 .
我当前的架构如下所示:
user_id | timestamp | book_id | author_id
user_id是分区键,timestamp是排序键 .
我遇到的问题是,使用此架构,我只能查询单个用户(分区键)已读取的书籍的详细信息 . 这是我的要求之一 .
另一个要求是查询在特定日期范围内创建的所有记录,例如:过去7天内创建的记录 . 使用此架构,我无法运行此查询 .
我已经研究了很多其他选项,并没有找到一种方法来创建一个允许我运行这两个查询的模式 .
-
检索单个用户读取的书籍记录(可以完成) .
-
检索过去x天内所有用户读取的图书记录(无法执行此操作) .
我不想运行扫描,因为它会很昂贵,我查看了使用GSI进行时间戳的选项,但它要求我指定一个哈希键,因此我无法查询在两个日期之间创建的所有记录 .
2 回答
一个天真的解决方案是创建一个GSI,在所有书籍中使用常量哈希键,并将时间戳作为范围键 . 这将允许您执行您的查询类型 .
这种方法的问题在于它很可能成为缩放瓶颈,因为相同的散列键意味着相同的节点 . 此问题的一种解决方法是进行分片:创建一组散列键(例如:从1到10),并将此集中的随机键分配给每本书 . 然后,当您进行查询时,您将需要进行10次查询并合并结果 . 您甚至可以将此设置大小设置为动态,以便它可以随您的数据进行扩展 .
我还建议查看此用例的其他工具(不是DynamoDB),因为DDB不是数据分析的最佳工具 . 例如,您可以将DynamoDB数据提供给CloudSearch或ElasticSearch,并在那里进行分析 .
一种解决方案可能是使用GSI并包括两个以上的列,当您将记录的接收日期作为主键(例如2017-07-02)和时间戳作为范围键04:22:33:000时 .
维护一个检查点表,其中包含表的进程名称和时间戳 . 每次从表中读取时,都可以更新检查点表以获取增量数据 . 如果您希望将过去7天的数据更改时间戳更改为过去7日期,并获取最近7天和当前时间之间的数据 .
您可以通过将日期作为分区传递并在关键字之间使用作为范围条件的时间戳来使用查询规范 .
您将从检查点表和当前日期计算日期差异,因此您将获得数据 .