DynamoDB中的时间戳应该使用哪种数据类型?


97

我是DynamoDB的新手。我希望创建一个表,该表使用DeviceID作为哈希键,使用Timestamp作为我的范围键和一些数据。

{ DeviceID: 123, Timestamp: "2016-11-11T17:21:07.5272333Z", X: 12, Y: 35 }

在SQL中,我们可以将datetime类型用作时间戳,但在DynamoDB中则没有。

  1. 我应该使用哪种数据类型?串?数?
    在此处输入图片说明

  2. 对于所选的数据类型,我应该写入哪种时间戳格式?ISO格式(例如:2016-11-11T17:21:07.5272333Z)或时期(例如:1478943038816)?

  3. 我需要在表格中搜索一段时间,例如:2015年1月1日上午10:00:00到2016年12月31日晚上11:00:00



2
我们使用纪元时间/格式的数字。我们使用它的搜索范围,以及用基本上是沿着CUSTOMER_ID
乔治·惠特克中号

可以使用字符串和数字数据类型。存储ISO8601格式时为字符串,存储纪元时间时为Number。这里更多的信息:abhayachauhan.com/2017/12/...
Abhaya肖汉

官方文档说,“你可以使用字符串数据类型来表示日期或做这个时间戳。一种方法,通过使用ISO 8601名的字符串是”。

你从(复制你的截图答案stackoverflow.com/a/27894543/1357094),回答了这个问题-这问题实际上重复提到答案的问题摆在首位: stackoverflow.com/questions/27894393/...
cellepo

Answers:


82

字符串数据类型应该用于日期或时间戳。

您可以使用String数据类型表示日期或时间戳。一种实现方法是使用ISO 8601字符串,如以下示例所示:

2016-02-15

2015-12-21T17:42:34Z

20150311T122706Z

日期或时间戳的DynamoDB数据类型

是的,当日期存储为字符串时,支持范围查询。该BETWEEN可以FilterExpresssion使用。我使用以下过滤器表达式获得了结果中的项目。

没有时间的FilterExpression:-

FilterExpression : 'createdate between :val1 and :val2',
ExpressionAttributeValues : {
        ':hkey' : year_val,
        ':rkey' : title,
        ":val1" : "2010-01-01",
        ":val2" : "2010-12-31"
    }

带时间的FilterExpression:-

FilterExpression : 'createdate between :val1 and :val2',
    ExpressionAttributeValues : {
        ':hkey' : year_val,
        ':rkey' : title,
        ":val1" : "2010-01-01T00:00:00",
        ":val2" : "2010-12-31T00:00:00"
    }

数据库值:

格式1-带有时区:

{"Item":{"createdate":{"S":"2010-12-21T17:42:34+00:00"},"title":{"S":"The Big New Movie 2010"},"yearkey":{"N":"2010"},"info":{"M":{"rating":{"N":"0"},"plot":{"S":"Nothing happens at all."}}}}}

格式2-无时区:-

{"Item":{"createdate":{"S":"2010-12-21T17:42:34Z"},"title":{"S":"The Big New Movie 2010"},"yearkey":{"N":"2010"},"info":{"M":{"rating":{"N":"0"},"plot":{"S":"Nothing happens at all."}}}}}

但是,当日期范围搜索存储为字符串值时,可以进行日期范围搜索吗?
Mark B

@notionquest是的,您可以使用String进行日期和时间范围搜索吗?
丹尼斯

54
我看不到您如何得出“日期或时间戳记使用字符串数据类型”的信息。该文档还说,您还可以通过纪元时间将Number数据类型用于日期。您为什么认为应该在Number上使用String ?
罗伊

1
可以使用字符串和数字数据类型。存储ISO8601格式时为字符串,存储纪元时间时为Number。这里更多的信息:abhayachauhan.com/2017/12/...
Abhaya肖汉

1
@roly数字也可以正常工作,但可读性较差。
马修·博尼格

22

数据类型取决于您的要求。

您可以使用ISO格式的字符串或使用纪元格式的数字。

ISO格式(字符串)的优点是易于阅读,但是DynamoDB不支持此格式的生存时间(TTL)。如notionquest所述,所有过滤器的工作方式都在“之间”和“范围”之内。

DynamoDB的生存时间(TTL)使您可以定义表中的项目何时过期,以便可以将其从数据库中自动删除。

使用纪元格式(数字)的优点是可以使用TTL功能和所有过滤器。

TLDR;

纪元格式(数字类型)-可以使用生存时间
ISO格式(字符串类型)-无法使用生存时间,但更易读


过滤器表达式可能受数字支持,但基于范围的关键条件仅受ISO格式的字符串支持
Rafael Almeida

@RafaelAlmeida,你是什么意思?您的来源是什么?
扎卡里·瑞安·史密斯

1
@ZacharyRyanSmith我错了-实际上,Number属性确实可以用作排序键和过滤器中的“关键条件”。
拉斐尔·阿尔梅达

2

Number数据类型String数据类型

可以用于日期或时间戳-不仅仅是字符串,因为在忽略数字的同时,此问题的接受答案错误地挑出了答案。

您可以使用数字数据类型表示日期或时间戳。一种方法是使用纪元时间-自1970年1月1日00:00:00 UTC以来的秒数。例如,纪元时间1437136300代表2015年7月17日UTC的12:31:40。

有关更多信息,请参见http://en.wikipedia.org/wiki/Unix_time

...

您可以使用String数据类型表示日期或时间戳。一种实现方法是使用ISO 8601字符串,如以下示例所示:

2016-02-15

2015-12-21T17:42:34Z

20150311T122706Z

有关更多信息,请参见http://en.wikipedia.org/wiki/ISO_8601

日期或时间戳的DynamoDB数据类型


1

为了能够在发送查询请求时过滤掉结果,我为DateTime使用了纪元格式,它比使用字符串更有效。

想象一下以下情况:最近31天,过去24小时,...再次使用字符串格式都可以实现,因为它也具有Begins_with运算符(请检查AWS doc上以下链接中的第3个示例),但是就数值而言,数值更有效排序(比较)和计算时的性能。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions

将日期时间转换为纪元格式很容易

Javascript:

var date = new Date();
var epoch = date.getTime();

// converting back to date-time
var initial_date = new Date(epoch);

C#

var date = DateTime.UtcNow;
var epoch = new DateTimeOffset(date).ToUnixTimeSeconds();

// converting back to date-time
var initial_date = DateTimeOffset.FromUnixTimeSeconds(epoch);

蟒蛇

import time
epoch = time.time()
 
# converting back to date-time
initial_date = time.gmtime(epoch )
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.