繁体   English   中英

用于部分比较的 Dynamodb 设计建议

[英]Dynamodb design recommendations for partial comparisons

我目前有一个包含以下列的 Dynamodb 表 - Id(分区键)、NativeTimestampAndPath(范围键)、EntryTimestamp(属性)。 目前没有二级索引。

示例数据如下所示:

Id (Partition Key)         |     NativeTimestampAndPath (Range Key)                             |     EntryTimestamp
event1#type1#eventid1      |     1960-01-01T00:00:00Z#event/event_name=event_1/event_type=type=1/day=15/eventid1-file1.json    |   2012-01-15T00:00:00Z  
event1#type1#eventid1      |     1970-01-01T00:00:00Z#event/event_name=event_1/event_type=type=1/day=16/eventid1-file2.json    |   2012-01-16T00:00:00Z  
event2#type1#eventid2      |     1970-01-01T00:00:00Z#event/event_name=event_2/event_type=type=1/day=17/eventid2-file1.json    |   2012-01-17T00:00:00Z  
event2#type1#eventid2      |     2000-01-01T00:00:00Z#event/event_name=event_2/event_type=type=1/day=18/eventid2-file2.json    |   2012-01-18T00:00:00Z 

所需的访问模式:

  1. 如果给定IdNativeTimestampAndPath值在表中尚不存在,则有条件地插入到表中。
  2. 搜索给定Id的所有NativeTimestampAndPath值。
  3. 搜索给定Id的所有NativeTimestampAndPath值,这些值equal/greater than/greater than or equal/less/less than or equal给定时间戳。 例如,如果我给定的时间戳是1970-01-01T00:00:00Z并且条件是查找包含小于或等于给定时间戳的时间戳的所有NativeTimestampAndPath ,则搜索查询应仅返回上表中的前 3 行。
  4. 搜索给定Id的所有NativeTimestampAndPath值,并仅返回 1 个包含所有最大/最小时间戳的NativeTimestampAndPath值。

总之,模式 3 和模式 4 只需要比较NativeTimestampAndPath列值的时间戳部分。

在实现此比较逻辑时,我注意到我得到的equal/greater than/greater than or equal/less/less than or equal条件的结果不准确,因为 Dynamodb 正在将给定的时间戳与整个值(包括时间戳和路径)进行比较NativeTimestampAndPath列。 不准确的结果是词法比较的结果,而不是时间戳与时间戳比较的结果。

比较逻辑代码:

DynamoDBQueryExpression<Event> queryExpression = new DynamoDBQueryExpression<Event> ();
queryExpression
        .withHashKeyValues (event)
        .withConsistentRead (false);
queryExpression.setLimit (500);
FilterType.Conditional operator = filterDto.getTimestampOperator (); // comparison condition string
Instant                givenTimestamp  = filterDto.getTimestamp (); // given timestamp
if (operator != null && givenTimestamp != null) {
    Condition rangeKeyCondition = new Condition ();
    switch (operator) {
        case eq:
            rangeKeyCondition.withComparisonOperator (ComparisonOperator.BEGINS_WITH);
            break;
        case gt:
            rangeKeyCondition.withComparisonOperator (ComparisonOperator.GT);
            break;
        case ge:
            rangeKeyCondition.withComparisonOperator (ComparisonOperator.GE);
            break;
        case lt:
            rangeKeyCondition.withComparisonOperator (ComparisonOperator.LT);
            break;
        case le:
            rangeKeyCondition.withComparisonOperator (ComparisonOperator.LE.toString ());
            break;
    }
    rangeKeyCondition.withAttributeValueList (new AttributeValue ().withS (String.valueOf (givenTimestamp)));
    queryExpression.withRangeKeyCondition ("NativeTimestampAndPath", rangeKeyCondition);
}
FilterType.Aggregate aggregate = filterDto.getTimestampAggregator (); //specifies if max or min is required
if (aggregate != null) {
    queryExpression.setLimit (1);
    switch (aggregate) {
        case max:
            queryExpression.setScanIndexForward (false);
            break;
        case min:
            queryExpression.setScanIndexForward (true);
            break;
    }
}
QueryResultPage<Event> paginated;
List<Event>            result = new ArrayList<> ();
do {
    paginated = dbMapper.queryPage (Event.class, queryExpression);
    result.addAll (paginated.getResults ());
    queryExpression.setExclusiveStartKey (paginated.getLastEvaluatedKey ());
} while (paginated.getLastEvaluatedKey () != null && aggregate == null);
return result;

假设我想:

  • Id保留为分区键,将NativeTimestampAndPath为范围键
  • 并且只对访问模式 3 和 4 使用查询表达式(相对于扫描表达式)

我可以对该 Dynamodb 设计做些什么来满足所需的访问模式条件? 非常感谢任何建议。 谢谢!

是的,排序键将被视为一个字符串。 1970-01-01T00:00:00Z#event/event_name=event_1/event_type=type=1/day=16/eventid1-file2.json小于或等于1970-01-01T00:00:00Z 不,它在词法排序上稍晚一些。 如果您在时间戳之后有额外的数据,则不可能在此处直接包含任何相等性期望。

这是诀窍。 那个长字符串是否小于1970-01-01T00:00:00Z$ 是的。 因为$是ASCII中#上面的一个字符,所以。 小于这个带有美元符号的值实际上将被视为小于或等于。 您可以使用 ! 对于另一个方向。

我不确定您对#4 的看法是什么。 您可以使用ScanIndexForward指定Limit和控制方向。 时间戳相同的关系将是随机选择的,但这与此处的数据 model 无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM