【问题标题】:Best practice for storing the date in MySQL from PHP从 PHP 将日期存储在 MySQL 中的最佳实践
【发布时间】:2010-11-10 03:11:46
【问题描述】:

我一生都在使用 unix 时间戳。

我喜欢它,因为它易于比较,它速度很快,因为我将它存储为整数。由于我使用的是 PHP,因此我可以使用 unixtimestamp 中的 date() 函数获取任何日期/时间格式。

现在,有人说最好使用 DATETIME 格式。但除了更合适的名字,我看不出有什么好处。

使用DATETIME确实更好,如果可以,有什么好处?

谢谢。

【问题讨论】:

    标签: mysql datetime unix-timestamp


    【解决方案1】:

    如果您将日期作为 Unix 时间戳存储在数据库中,那么您就给自己带来了繁重的工作。您必须将它们转换为您想要使用的格式,您必须在日期范围之间进行计算,您必须构建查询以获取某个范围内的数据。这似乎违反直觉——您的“程序员时间”肯定最好花在解决实际问题上吗?

    以 MySQL 可用的适当格式存储日期和时间,然后使用数据库函数为您想要的数据创建查询,这似乎是更好的做法。与花在阅读(和理解)11.6 MySQL Date and Time Functions

    【讨论】:

    • 我不同意。检查我的答案。
    • MySQL 的 DATETIME 字段缺少时区 - 始终以 UTC 存储日期(即避免使用 NOW() - 使用 UTC_TIMESTAMP()),否则当您尝试将应用程序国际化时,您将陷入混乱并且出于任何原因更改您的服务器时区。
    【解决方案2】:

    我也一直是 unix 时间戳的忠实粉丝。但我认为正确的答案是:“取决于”。我最近做了一个单表数据库,我只想列出 URL。会有一个日期字段,但日期字段纯粹是为了排序。即按 last_crawled 排序。这意味着我永远不会在该字段上使用任何内置日期函数。这只是首先获取最旧条目的一种简单方法,我永远不会将日期函数应用于该字段。现在,如果我把它设为日期字段,我会失去两件事:

    1. 日期时间字段的大小是整数的两倍
    2. 按整数排序更快(这不是 100% 肯定,pending outcome of this question

    但是,对于另一个系统,我必须存储交易信息。这使得使用internal mysql date functions 成为可能,这在我们必须开始做报告时非常有用。

    【讨论】:

      【解决方案3】:

      使用MySQL date/time types 的一个优点是能够更简单地使用date/time functions in MySQL

      DATE 类型的优点还在于它只存储日、月和年,因此不会浪费空间或比较复杂的情况,因为从纪元时间开始的几秒钟对于您只关心一天而不关心的情况时间。

      就我个人而言,我倾向于将数据库用作数据的转储,因此对此类功能没什么兴趣。在 PHP 中,出于您所说的原因,我倾向于仅以整数格式存储日期。

      【讨论】:

        【解决方案4】:

        @Smita V,您引用的低效查询只是因为您将转换函数错误地应用于每个表行,您应该将其应用于条件本身。所以不是

        select col1,col2,colUnixdatetime from table where From_Unixtime(colUnixdatetime) between wtvdate1 and wtvdate2
        

        ,它将表格上的每一行转换为与您获得的日期进行比较。你应该使用

        select col1,col2,colUnixdatetime from table where colUnixdatetime between UNIX_TIMESTAMP(wtvdate1) and UNIX_TIMESTAMP(wtvdate2). 
        

        这样做会使用适当的表索引。

        @treznik 前段时间我从 uts 整数转换为 datetime 或 timestamp 数据类型,原因如上所述,因为它们更容易阅读和操作(我做了很多直接表访问) .不过,我最近开始重新考虑这种方法,原因有两个:

        1. 没有存储时区位置,因此您是根据您的位置推断时区。这对您来说可能是也可能不是问题。
        2. 它忽略夏令时。因此,当时钟在凌晨 2 点返回时,您将获得两次凌晨 1:30,并且说 2011-10-30 01:30 不会让您知道这一点,而 1319938200 会。我认为 mysql 中没有本地方式来存储包括时区在内的日期,除了作为字符串 (2011-10-30 01:30 BST)。

        我自己仍在尝试找出答案。

        【讨论】:

        • 告诉我吧,不敢相信这已经是 3 年前的事了。在我开始这个帖子后不久,我也切换到 datetime,但从未真正相信这是正确的选择。我经常遇到你所说的同样的问题,我仍然认为时间戳是最终的选择。但我想有时候,为了完成任务,我们需要让步并采用最实际的解决方案。
        • 虽然 datetime 没有时区,但我们将日期存储为 UTC,并在应用层或使用 convert_tz() 转换为适当的时区。这解决了你的两个问题。
        • 此外,我认为 datetime 实际上比时间戳更可靠,因为我知道该值始终是我存储的值(以 UTC 格式),而不是存储为 UTC 但转换为服务器的时区(可能会改变)。
        【解决方案5】:

        使用数据库日期时间更有效,因为每次需要查询时,都需要应用 from_unixtime() 函数从表的 unix datetime col 中提取数据。在 where 子句中使用这个函数将完全忽略任何索引的使用。

        说我的查询是:

        从 wtvdate1 和 wtvdate2 之间 colUnixdatetime 的表中选择 col1,col2,colUnixdatetime

        我需要跑步:

        从 wtvdate1 和 wtvdate2 之间的 From_Unixtime(colUnixdatetime) 表中选择 col1,col2,colUnixdatetime

        上面的查询将完全忽略任何索引,这里没有使用索引,因为它们永远不会被使用,因为我总是必须使用一个函数来获取真正的日期时间。

        where 子句中条件 LHS 上使用的任何内置函数都不会使用任何索引,如果您有一个 HUGE 表,您的查询将花费更长的时间。

        【讨论】:

          【解决方案6】:

          更容易维护是一个优点。查看实际日期:

          select * from table where ...
          

          挺好看的。

          【讨论】:

            【解决方案7】:

            比较容易,mysql提供了很多日期函数。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-11-08
              • 2018-04-29
              • 2019-06-05
              • 2012-10-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多