【问题标题】:What is the best way to store dates in MongoDB?在 MongoDB 中存储日期的最佳方式是什么?
【发布时间】:2011-07-20 15:56:18
【问题描述】:

我刚开始学习 MongoDB,希望能慢慢从 MySQL 迁移过来。

在 MySQL 中,有两种不同的数据类型 - DATE ('0000-00-00')DATETIME ('0000-00-00 00:00:00')。在我的 MySQL 中,我使用 DATE 类型,但我不确定如何将它们传输到 MongoDB。在MongoDB中,有一个Date对象,相当于DATETIME。使用Date 对象似乎是最合适的,但这会浪费空间,因为没有使用小时、分钟、秒。另一方面,将日期存储为字符串似乎是错误的。

在 MongoDB 中存储日期 ('0000-00-00') 是否有黄金标准?

【问题讨论】:

  • @DanDascalescu :这不是重复的。您提到的讨论是关于日期/时间的,而这里是关于如何在没有时间的情况下存储日期。

标签: mongodb


【解决方案1】:

我实际上正在转换 MongoDB 数据库,其中日期存储为正确的 Date() 类型,而不是将它们存储为yyyy-mm-dd 形式的字符串。为什么,考虑到所有其他回答者都说这是一个可怕的想法?简单地说,由于我在尝试使用 JavaScript 中的日期时一直在遭受无休止的痛苦,它没有(真正的)时区概念。我一直在 MongoDB 中存储 UTC 日期,即一个 Date() 对象,其中包含我想要的日期和时间设置为午夜 UTC,但是将用户提交的日期从他们的任何时区正确转换为出乎意料的复杂和容易出错碰巧在。我一直在努力让我的 JavaScript“无论本地时区到 UTC”代码都能正常工作(是的,我知道 Sugar.js 和 Moment.js),我已经决定像这样的简单字符串好的旧 MySQL 标准 yyyy-mm-dd 是要走的路,我将在客户端运行时根据需要解析为 Date() 对象。

顺便说一句,我还尝试将此 MongoDB 数据库与 FileMaker 数据库同步,该数据库也没有时区的概念。对我来说,存储时间数据的简单性,尤其是当它像 UTC 午夜一样毫无意义时,有助于确保代码更少错误,即使我必须不时地解析字符串日期。 p>

【讨论】:

  • 点赞。将日期存储为 BSON UTC 日期/时间的最大缺点不是存储。它使您可以处理它们根本不适用的时区,并且比解析简单的日期字符串要困难得多。我还建议在 MongoDB 中将日期表示为字符串。
  • 同意。此外,令我惊喜的是,$gt$lt 可以根据需要使用存储为字符串的日期:.find({created: {$gt: '2012-01-01'}} 实际上会返回自 2012 年 1 月 1 日以来创建的所有文档。
  • 我很高兴我没有使用 yyyy-mm-dd 在 MongoDB 中存储日期。
  • 这样你就失去了所有的日期聚合选项。
  • @ŁukaszFrankowski,从 3.6 版开始,您可以使用 $dateFromString。
【解决方案2】:

BSON(mongo 原生使用的存储数据格式)有一个dedicated date type UTC datetime,它是一个 64 位(即 8 字节)有符号整数,表示自 Unix 时间纪元以来的毫秒数。使用任何其他类型来存储日期和时间戳的正当理由很少。

如果您迫切希望每个日期保存几个字节(同样,使用 mongo 的填充和最小块大小以及所有这些仅在极少数情况下值得麻烦),您可以通过存储将日期存储为 3 字节二进制 blob它是yyyymmdd格式的无符号整数,或2个字节二进制词斑点,表示“自x年1月1日以来的日子”,必须适当地选择x,因为它仅支持179年的日期范围。

编辑:正如下面的讨论所示,这只是在极少数情况下可行的方法。 基本上;使用 mongo 的原生日期类型;)

【讨论】:

  • 二进制字段包括4字节长度和1字节子类型,所以空二进制字段占用5字节。
  • 我知道。为了澄清,这将在一个 blob 中存储多个日期。花费大量精力删除几个字节的唯一正当理由是当您有很多日期要存储时。我认为这是在 OP 中暗示的。
  • 这种存储方式也会使日期不可索引且更新繁琐。开发您的打包想法可以使用一些快速压缩库(如 Google Snappy)。
  • 有效的用例是避免在 JavaScript 中处理时区的困难。请看下面我的回答。我发现处理像yyyy-mm-dd 这样的解析/格式化字符串比尝试协调客户端和服务器时区并在适当的日期创建Date() 对象更容易。请记住,我们在这里只保存日期,而不是日期时间。
  • @Geoffrey 我指的是使用二进制数据来存储日期。将它们存储为字符串是完全有效的。也就是说,我强烈支持从不处理服务器端的时区,并将所有内容存储为 UTC。之后,您可以在客户端上进行时区转换。干净多了。
【解决方案3】:

如果您真的关心每个字段保存 4 个字节(如果每个文档有很多 DATE 字段),您可以将日期存储为 int32 字段,格式为 20110720(注意 MySQL DATE 占用 3 个字节,所以存储在任何情况下都会更大)。否则我最好坚持标准的日期时间类型。

【讨论】:

    猜你喜欢
    • 2013-06-14
    • 2017-09-18
    • 1970-01-01
    • 2021-10-22
    • 2016-12-22
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多