使用哈希和范围主键的性能:Dynamodb

时间:2015-07-31 23:10:06

标签: javascript node.js amazon-dynamodb loopbackjs

我正在使用Node.js和loopback构建应用程序。应用程序的一个组件是将登录尝试存储到DynamoDB中。我对这个数据库很新,我遇到了问题。

目前,我的哈希键是一封电子邮件,我的范围键是登录尝试发生时的unix-timestamp。本质上,我需要从数据库中获取所有数据,以生成最后一次登录尝试的列表。首先想到的是使用扫描,但它不允许根据持续的登录尝试对列表进行排序。使用查询的问题是,我必须访问所有电子邮件,而不仅仅是特定于某个特定电子邮件的项目。我认为我可以使所有哈希值相同,但是这将根据dynamoDB存储其数据的方式在未来发生性能问题。

是否有其他人遇到此类问题并有解决方案?

2 个答案:

答案 0 :(得分:1)

像Amazon DynamoDB这样的NoSQL数据库最适合通过特定主键(“哈希”)存储和检索数据。也可以通过主键和附加值(“哈希和范围”)来识别数据。

但是,您想要了解“上次登录”的要求并不适合NoSQL数据库,因为扫描数据非常耗费CPU和IO。

另一种方法是为每个用户创建一个Item(记录),并在用户上次登录时间的该Item上存储一个Attribute(类似于“Column”的概念)。这样,您只需要检索一条特定记录即可发现上次登录时间。

如果您还希望保留登录尝试的完整历史记录,则可以在单独的表上执行此操作,其中包含哈希和范围以及每次登录尝试一个项目。这将与上面的表格分开,每个用户只有一个项目。

答案 1 :(得分:0)

您可以尝试对unix时间戳进行bucketizing,以便从DynamoDB的查询功能中受益。

示例模式:

  • 哈希键=日期
  • 范围键=时间戳
  • 其他属性=电子邮件

示例项目: {“date”:“07/31/2015”,“timestamp”:1438393927,“email”:“abc@def.com”}

使用此架构,特定日期内的所有登录尝试都将存储在相同的哈希键下。您可以通过提供当前日期作为哈希键来有效地查询最近的登录。您甚至可以进一步向下钻取并使用哈希键代表一个小时。

示例查询:

  • KeyConditions:{“date”=“01/01/2015”}
  • ScanIndexForward:false //最近登录首先

示例结果:

  • {“date”:“01/01/2015”,“timestamp”:1420153200,“email”:“abc@xyz.com”}
  • {“date”:“01/01/2015”,“timestamp”:1420153199,“email”:“def@xyz.com”}
  • {“date”:“01/01/2015”,“timestamp”:1420153198,“email”:“abc@xyz.com”}

Pro :均匀分布的数据,可扩展,良好的时间局部性,可实现基于时间的高效查询

Con :查询日期范围/存储桶的登录尝试并不那么简单。即,过去3天的登录需要3个单独的查询(每个日期一个)

PS :如果您的查询模式同时需要按日期和电子邮件查询,请使用全局二级索引(GSI)http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html