针对查询的DynamoDB NoSQL设计

时间:2017-02-16 11:51:23

标签: amazon-dynamodb nosql

我希望存储用户事件的日志。这将是很多条目,所以我认为DynamoDB会很好,因为其他一切都在那里托管。

我需要以两种方式查询这些事件,即用户日期(范围)的事件总数,以及偶尔日期的所有事件。

我打算将其作为user id(密钥),sequence number(密钥),datetimeduration存储在一个表中。< / p>

它应该是多个表吗?如何最有效地完成这项工作?

2 个答案:

答案 0 :(得分:0)

对于少量数据,这种结构是可以的。 请记住,序列号(您的范围键)必须由您提供。选择日期作为unix时间戳,以毫秒精度作为排序键似乎是个好主意。

不需要额外的表格。 但是,您的结构在很大程度上取决于您想要实现的读写容量和数据大小。

假设您的user_id是您的分区键。

对于每个不同的分区键值,所有表和索引项的总大小不能超过10 GB。 单个分区最多可支持3,000个读取容量单位或1,000个写入容量单位。

您需要考虑这些限制来创建分区键。 例如,非常活跃的用户有许多事件,因此您需要超过1000个写入容量单位。不幸的是,您已选择用户ID作为分区。

在这种情况下,您只能使用1000个写入容量单位,因此可能会出现故障。

您需要拥有不同的结构。例如,分区名称就像 user_id_1 user_id_2等因此,分区命名机制根据应用程序的需要将数据传播到分区。

检查关于dynamodb限制的这些链接。

Tables guidancePartition distribution

答案 1 :(得分:0)

我建议你的事件表采用以下结构:

  • 用户ID - 哈希密钥
  • 事件日期/时间(以毫秒为单位的时间戳) - 范围键
  • 持续时间

将事件时间戳作为范围键应该足以为事件提供唯一性(除非用户可以在同一毫秒内拥有多个事件),因此您不需要序列号。

拥有这样的架构,您可以使用简单的query为用户获取日期的所有事件。

不幸的是,DynamoDB不支持聚合查询,因此您无法快速获得用户的总事件数(您必须查询所有记录并手动计算总数)。 因此,我建议为用户事件统计信息创建单独的表,如下所示:

  • 用户ID - 哈希密钥
  • 日期 - 范围键
  • events_cnt(日期用户的事件总数)

因此,在事件表中添加新记录后,您必须在统计信息表中为用户增加事件计数器,如下所示:

var dynamodbDoc = new AWS.DynamoDB.DocumentClient();
var params = {
  TableName : "user_events_stats",
  Key: {
      userId: "65716110-f4df-11e6-bc64-92361f002671" ,
      date:   "2017-02-17",
  },
  UpdateExpression: "SET #events_cnt = if_not_exists(#events_cnt, :zero) + :one",
  ExpressionAttributeNames: {
      "#events_cnt": "events_cnt",
  },  
  ExpressionAttributeValues: {
      ":one": 1,
      ":zero": 0,
  },  
};

dynamodbDoc.update(params, function(err, data) {

});