【问题标题】:Should Dates be Stored as a Datetime or as an int in SQL?日期应该存储为日期时间还是 SQL 中的 int?
【发布时间】:2009-03-31 17:28:20
【问题描述】:

我在日期时间 (0000-00-00 00:00:00) 中存储我在论坛中发帖的所有日期。 我看到 phpBB、punBB 和所有流行的论坛都将日期存储在 int 中?

什么更好?

【问题讨论】:

    标签: php sql


    【解决方案1】:

    如果您将日期存储为 INT,那么每个连接到您的数据库的应用程序或工具都必须知道如何将该 INT 转换为有意义的东西。我建议坚持使用适合数据的数据类型,除非您的特定 RDBMS 对特定数据类型存在严重缺陷。

    还有一个需要考虑的问题...如果您将它们存储为 INT,那么您还将无法访问许多特定于日期的函数,并且必须自己编写它们。例如,返回特定日期的日期名称(星期一、星期二等)。

    【讨论】:

    • 您可以随时向其他应用程序提供视图可以正确转换 INT 日期
    • 也许吧,但由于日期往往相当普遍,因此会产生大量视图和额外维护,只是为了支持一些对我来说没有明确意义的东西。
    • @mike:以语言专有的 int 格式存储日期并提供代表真正本机类型的视图有什么意义?如果有的话,将它们存储为 DateTimes 并提供一个以专有 int 格式表示日期的视图会更合理。
    • 这个建议的问题是你可能使用了几种语言、dbms 产品和其他工具,它们都有不兼容的日期时间转换,并最终在它们之间编写映射库(虽然大多数都有可用的整数转换 - 参见 MySQL 的 UNIX_TIMESTAMP() 函数。
    【解决方案2】:

    我不确定是否有“更好”的答案。但我会推荐日期时间,因为如果你将它们存储为 int,你可能会遇到Year 2038 issue.

    【讨论】:

    • 不要忘记 10000 年的问题:在这一点上,所述格式的日期不再具有词法可比性 ;-)
    • 哈哈!如果我的软件在 7991 年后还能运行,人类就完蛋了。
    【解决方案3】:

    我对所有时间字段都使用 DATETIME(并且,使用 MySQL,我总是,总是避免使用 TIMESTAMP)。不过,我使用的一个技巧是将列设置为 NULL DEFAULT NULL。这样,对于我认为日期为空或空白的情况,我无需担心或检查“0000-00-00 00:00:00”;我只检查IS NULL

    我能想到过去人们可能考虑将 INT 用于他们的日期列的唯一原因是因为有一次,MySQL 在内部将 DATETIME(以及 DATE 和 TIME)实现为字符串。在这种情况下,DATETIME 字段将比 INT 字段大得多,因此如果空间是一个问题,我可以看到正在做出该决定。如今,情况已不再如此(我会说 MySQL 4.x 及更高版本),没有充分的理由不再选择 DATETIME。

    【讨论】:

      【解决方案4】:

      此外,前纪元日期也存在问题。在 INT 中保留成员出生日期之类的信息很困难,因为有些成员可能出生在 1970 年 1 月 1 日之前。

      【讨论】:

        【解决方案5】:

        如今,大多数 DBMS 都允许您对真实的日期时间字段进行更时髦的查询。使用可用于日期操作和查询的函数,很难证明使用整数是合理的。

        我想大多数 BB 系统都使用 INT,因为它们更容易在多个数据库引擎中实现,如果您只关心日期部分而不是时间部分,那么您可能会从 INT 中获得稍微更好的性能,而不是到日期时间(通常是 8 字节浮点数)。

        就我个人而言,我更喜欢将日期存储在日期时间字段中,因为我几乎从不从一个数据库平台迁移到另一个数据库平台,例如,向数据库询问每个月的最后一个星期五是有好处的。

        【讨论】:

          【解决方案6】:

          最佳答案是“视情况而定”。如果没有其他信息,我会说 datetime 更好。我认为这些论坛的实现是未能识别更好、更成熟的数据类型。你必须想出一个很好的理由来解释为什么你想要整数超过日期。也许他们有,我只是不知道。

          【讨论】:

            【解决方案7】:

            在内部,日期时间是一个整数,从某个纪元开始的秒数或毫秒数,通常是 1970 年 1 月 1 日午夜的 linux 纪元。

            但它允许您使用各种美妙的日期函数来添加、减去和分解时间间隔,这是您无法使用 int 完成的(无需自己重写所有这些函数)。

            因此,通过使用日期/日期时间而不是 int,您不会失去任何东西,并且会像其他人回答的那样获得很多。

            【讨论】:

              【解决方案8】:

              我使用将日期存储为 int 的数据仓库,例如20090331 格式。然后有一个表格专门用于将该 int 转换为任何与日期相关的信息,包括日期时间表示。这提供了很大的灵活性,让我们可以添加额外的信息,例如季度编号、假期指定等。如果您需要除整数日期之外的任何内容,只需加入日期表即可。

              select MyTable.Stuff,DimDate.AsDateTime,DimDate.BusinessQuarter,DimDate.IsHoliday from MyTable
              inner join DimDate on MyTable.DateKey = DimDate.DateKey
              

              【讨论】:

              • 这不是一个整数。是的,但是它允许非法值,例如 20090332。而且它不容易映射,因为您必须跳过这些非法值才能将其映射到日期。这意味着您必须继续维护您的翻译/查找表。
              • 是的,维护查找表很痛苦。但是您可以使用外键约束将整数限制为表中已有的值。您还可以定义 NextDay 和 PreviousDay 列,甚至是像 NextWorkDay 这样的复杂概念。
              【解决方案9】:

              SQL 2008 引入了“日期”数据类型,它小于完整的“日期时间”字段,如果您不需要时间部分(如果您正在考虑使用 INT,听起来您不需要反正不需要)。

              详情请见this article

              【讨论】:

                【解决方案10】:

                我想跟进 tpdi 的回答,并描述我多次以两种方式完成的经历。

                当使用整数时,它是按照 tpdi 所描述的约定完成的——在 1970 年左右的某个时间点过去的给定秒数。

                当许多生产软件至少部分用 C 编写时,这种模式是(UNIX 风格的)标准,并且为映射和日期计算提供了合理数量的函数。

                上面没有过多讨论的一个问题是,按小时、分钟和秒进行的插值并不是所有语言和 DBMS 库都能很好地处理。基于整数的日期可以更好地处理此问题,而无需担心舍入错误 - 至少只要您不需要小于 1 秒的分辨率。不需要处理 0 之前的日期也很有帮助,尽管它可以在处理负整数时没有太多麻烦。

                最后的好处可能是大多数语言/DBMS 都具有处理这种约定的功能,这使得使用多种语言和 DBMS 产品变得更加容易,并且兼容性问题更少。

                在某些合理的情况下,它就像@tpdi 所描述的那样;但它也可以完全颠覆 - 如果它们适合您的上下文,您可能会通过处理整数日期时间的库失去精度和跨语言兼容性。

                【讨论】:

                  【解决方案11】:

                  我会使用 Datetime,除非有 other dates 和可能的 times 可以更好地存储为 int

                  【讨论】:

                    【解决方案12】:

                    仅供参考,如果您使用 int/timestamp,那么您仍然可以获得您的 RDBMS 可以为日期/时间提供的所有功能。例如,在 MySQL 中,FROM_UNIXTIME(timestamp) 采用整数时间戳并返回 DATETIME,然后您可以随意使用。

                    对于冗长的讨论,没有比 Drupal 项目的优秀人员更好的了:http://groups.drupal.org/node/731

                    希望这会有所帮助。

                    【讨论】:

                    • 这不是真的:尝试表示 1970 年之前的日期。你不能
                    猜你喜欢
                    • 2018-03-14
                    • 2016-11-20
                    • 1970-01-01
                    • 2011-10-26
                    • 2016-08-07
                    • 2011-09-06
                    • 1970-01-01
                    • 2012-05-29
                    • 1970-01-01
                    相关资源
                    最近更新 更多