【问题标题】:Best approach to handle Java8 date and time in DynamoDB在 DynamoDB 中处理 Java8 日期和时间的最佳方法
【发布时间】:2017-11-10 08:28:28
【问题描述】:

我研究了使用 Java SDK 存储日期和时间的 DynamoDB 选项。据我所知,Java8 LocalDate 和 LocalDateTime 需要自定义转换器,而对于旧的 Date、Calendar 和 Joda 时间 LocalDateTime 有一些注释。

根据文档,@DynamoDBTypeConvertedTimestamp 支持标准的 Date 类型转换,例如 java.util.Calendar、Long。 @DynamoDBTypeConvertedEpochDate 可用于将日期、日历和 org.joda.time.DateTime 转换为数值。

同时,如果我不在 Date 字段上添加任何注释,它会被保存,就像它上面有 @DynamoDBTypeConvertedTimestamp 一样,甚至范围查询也可以成功。

是否有人知道解释不同的可能方法,并对从 DynamoDB 存储和检索 Java 日期和时间对象的最佳方法发表意见?

【问题讨论】:

    标签: amazon-dynamodb java-time


    【解决方案1】:

    TLDR;这取决于日期、时间等的使用方式。

    长答案

    这将取决于您的用例,因此没有硬性和快速的“最佳”方法。但是,有一些注意事项需要牢记。

    值在您的表架构中是如何使用的?

    如果要将 Java 8 日期/时间用作排序键,请考虑使用自定义转换器将其转换为字符串。如果这样做,则可以在查询的键条件表达式中使用begins_with 运算符,例如begins_with(myDate, "2018-12")。如果您想在特定的年、月、日、小时等中搜索所有内容,能够像这样进行查询将使您的代码更简单。

    如果您将该值用作DynamoDB TTL 属性,则必须将其转换为数字时间戳。这是使用 TTL 功能的要求。

    我们讨论的是java.time 中的哪一个?

    Some of the classes in the java.time package 没有自然的转换为数字。例如,LocalDate 最多只能转换为数字。将 LocalDate 2018-12-10 转换为 20181210 是最有意义的,但此时,您必须编写足够的代码,以便使用内置的 LocalDate.toString()LocalDate.parse()

    您需要多久查看一次数据库以追踪错误或修复错误数据?

    如果您经常在数据库中搞乱(希望不是这种情况),请使用人类可读的内容。当他们在半夜被寻呼时,没有人想知道2018-12-05T17:23:19.483+08:30 是在1544572463 之前还是之后。

    您的应用对延迟增加的敏感程度如何?

    我没有观察到与将日期存储为字符串与数字相关的 DynamoDB 的任何可衡量的性能差异。但是,string parsing is slower that using a number 会创建一个java.time 对象,因此如果您将日期存储为字符串,可能会对您的应用程序产生轻微影响。

    不要让自定义转换器吓跑您

    java.time api 编写它们真的很容易。下面介绍了如何为 LocalDateTime 实现一个转换器,该转换器可转换为 String

    public class LocalDateTimeToStringTypeConverter implements DynamoDBTypeConverter<String, LocalDateTime> {
    
        @Override
        public String convert(LocalDateTime localDateTime) {
            return localDateTime.toString();
        }
    
        @Override
        public LocalDateTime unconvert(String s) {
            return LocalDateTime.parse(s);
        }
    }
    

    【讨论】:

    • 不了解 DynamoDB 并好奇:​​它不是像标准 SQL 数据库那样有 datedatetimetimetimestamp with timezone 数据类型吗?如果没有:LocalDate 可以轻松转换为数字,即纪元日。不过,我仍然同意你更喜欢 2018-12-12 这样的文本表示。
    • @OleV.V. DynamoDB 更像是一个键值对或面向文档的数据库。它提供了一些基本的数据类型,以便您可以构建自己的丰富数据模型,并且对数据的含义不做任何假设。您可以在此处查看支持的数据类型:docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
    • @OleV.V.一些 SDK 提供其他数据类型的转换。例如,Java SDK 还支持DateCalendar,它将它们转换为毫秒精度的 ISO-8601 字符串。 docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
    【解决方案2】:

    尝试使用@DynamoDBTyped 注释日期字段,这是一个用于覆盖 dynamoDB 中标准属性类型绑定的注释。因此它将日期转换为 Attribute Type = S ,即 DynamoDM 中的字符串。希望对你有帮助

    @DynamoDBTyped(DynamoDBAttributeType.S)
    private LocalDate startDate;
    

    【讨论】:

      猜你喜欢
      • 2012-10-09
      • 2011-04-17
      • 1970-01-01
      • 2015-01-28
      • 2018-03-16
      • 2015-01-03
      • 1970-01-01
      • 2011-04-16
      • 2021-09-26
      相关资源
      最近更新 更多