Amazon web services DynamoDB中的索引通知表

Amazon web services DynamoDB中的索引通知表,amazon-web-services,notifications,amazon-dynamodb,Amazon Web Services,Notifications,Amazon Dynamodb,我将要实现一个通知系统,并试图找出一种在数据库中存储通知的好方法。我有一个使用PostgreSQL数据库的web应用程序,但是关系数据库似乎并不适合这个用例;我希望支持各种类型的通知,每种类型都包括不同的数据,尽管数据的子集对于所有类型的通知都是通用的。因此,我认为NoSQL数据库可能比试图规范化关系数据库中的模式要好,因为这将非常棘手 我的应用程序托管在AmazonWebServices(AWS)中,我一直在研究DynamoDB存储通知的功能。这是因为它是管理的,所以我不必处理它的操作。理想情

我将要实现一个通知系统,并试图找出一种在数据库中存储通知的好方法。我有一个使用PostgreSQL数据库的web应用程序,但是关系数据库似乎并不适合这个用例;我希望支持各种类型的通知,每种类型都包括不同的数据,尽管数据的子集对于所有类型的通知都是通用的。因此,我认为NoSQL数据库可能比试图规范化关系数据库中的模式要好,因为这将非常棘手

我的应用程序托管在AmazonWebServices(AWS)中,我一直在研究DynamoDB存储通知的功能。这是因为它是管理的,所以我不必处理它的操作。理想情况下,我希望使用MongoDB,但我真的不希望自己处理数据库的操作。我一直在想办法在DynamoDB做我想做的事情,但我一直在努力,因此我有几个问题

假设我要为每个通知存储以下数据:

  • 身份证
  • 通知接收者的用户ID
  • 通知类型
  • 时间戳
  • 是否已阅读/看到
  • 关于通知/事件的元数据(无需对此进行查询)
现在,我希望能够查询给定用户的最新X通知。另外,在另一个查询中,我想获取特定用户的未读通知数。我正试图找出一种方法,我可以索引我的表,以便能够有效地做到这一点

我可以排除简单地使用散列主键的可能性,因为我不会简单地使用散列键进行查找。我不知道“散列和范围主键”是否对我有帮助,因为我不知道将哪个属性作为范围键。是否可以将唯一的通知ID用作哈希键,将用户ID用作范围键?这是否允许我仅通过范围键进行查找,即不提供哈希键?如果可能的话,也许第二个索引可以帮助我按时间戳排序

我还研究了全局二级索引,但问题是,在查询索引时,DynamoDB只能返回投影到索引中的属性——而且由于我希望返回所有属性,因此实际上我必须复制我的所有数据,这看起来相当荒谬


如何索引通知表以支持我的用例?有可能吗,或者你还有其他建议吗?

我是DynamoDB的活跃用户,下面是我要做的。。。首先,我假设除了按用户id获取最新通知外,您还需要单独访问通知(例如,将它们标记为已读/已看到)

表格设计:

NotificationsTable
id - Hash key
user_id
timestamp
...

UserNotificationsIndex (Global Secondary Index)
user_id - Hash key
timestamp - Range key
id
NotificationsTable
user_id - Hash key
id/timestamp - Range key
当您输入
UserNotificationsIndex
时,您将想要通知的用户的
user\u id
设置为
false
,并且DynamoDB将按相反的时间顺序返回该用户的通知id。您可以选择设置要返回多少结果的
限制
,或获得最大1MB

关于投影属性,您必须将所需的属性投影到索引中,或者您可以简单地投影
id
,然后在代码中编写“hydrate”功能,查找每个id并返回所需的特定字段

如果你真的不喜欢,这里有一个替代的解决方案给你。。。将您的
id
设置为您的
timestamp
。例如,我将使用自自定义纪元(例如2015年1月1日)起的毫秒数。以下是另一种桌子设计:

NotificationsTable
id - Hash key
user_id
timestamp
...

UserNotificationsIndex (Global Secondary Index)
user_id - Hash key
timestamp - Range key
id
NotificationsTable
user_id - Hash key
id/timestamp - Range key
现在,您可以直接查询NotificationsTable,适当设置
用户id
,并在范围键的排序上将
ScanIndexForward
设置为
false
。当然,这假设不会发生用户在同一毫秒内收到2个通知的冲突。这不太可能,但我不知道你们系统的规模

动机注意:当使用DynamoDB这样的云存储时,我们必须了解存储模型,因为这将直接影响 您的性能、可扩展性和财务成本。这是不同的 而不是使用本地数据库,因为您不仅为 存储的数据以及对其执行的操作 数据。例如,删除记录是一种写入操作,因此 你没有一个有效的清理计划(而且你的案子还在继续) 时间序列数据(特别需要一个),您将为此付出代价。你的 数据模型在处理小数据量时不会出现问题 但当你需要扩大规模时,它肯定会毁掉你的计划。那是 比如,创建(或不创建)索引、定义适当的 键的属性、创建表分段等都将 在未来的道路上,让一切变得不同。选择DynamoDB(或更多) 一般来说,键值存储)与任何其他体系结构 决策需要权衡,你需要清楚地理解 有关存储模型的某些概念,以便能够使用该工具 有效地,选择正确的键确实很重要,但只有 冰山一角。例如,如果你忽略了你是 处理时间序列数据,无论主键或索引是什么 您定义,您的配置吞吐量将不会得到优化,因为 它分布在整个表(及其分区)中,而不是 只有经常访问的数据,这意味着未使用的数据 直接影响您的吞吐量,仅仅因为它是同一系统的一部分 桌子这导致了以下情况:
通过puteExceedexception提供
Index Name: Notifications_April_Unread
Hash Key: UserId
Range Key : Unuread