您建议使用datetime或timestamp字段吗?为什么(使用MySQL)?

我在服务器端使用PHP。


当前回答

MySQL中的时间戳通常用于跟踪记录的更改,并且经常在每次更改记录时更新。如果要存储特定值,应使用datetime字段。

如果您希望在使用UNIX时间戳或本机MySQL日期时间字段之间做出选择,请使用本机datetime格式。您可以通过这种方式在MySQL中进行计算(“SELECT DATE_ADD(my_datetime,INTERVAL 1 DAY)”),如果您想用PHP对记录进行操作,那么在查询记录时,很容易将值的格式更改为UNIX时间戳(“SELECT UNIX_timestamp(my_datatime)”)。

其他回答

值得注意的是,在MySQL中,您可以在创建表列时使用以下内容:

on update CURRENT_TIMESTAMP

这将更新每次修改行时的时间,有时对存储的上次编辑信息非常有用。这只适用于时间戳,但不适用于日期时间。

以下示例显示了在将时区更改为“america/new_york”(DATETIME不变)后,TIMESTAMP日期类型如何更改值。

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

我已经把我的答案转换成了文章,这样更多的人可以发现这个有用的MySQL:日期时间与时间戳数据类型。

我建议不要使用DATETIME或TIMESTAMP字段。如果你想将一个特定的日子作为一个整体来表示(比如生日),那么就使用DATE类型,但是如果你要更具体一些,你可能会对记录一个实际的时刻感兴趣,而不是一个时间单位(日、周、月、年)。不要使用DATETIME或TIMESTAMP,而是使用BIGINT,只需存储自epoch以来的毫秒数(如果使用Java,则为System.currentTimeMillis())。这有几个优点:

避免供应商锁定。几乎每个数据库都以相对类似的方式支持整数。假设您想移动到另一个数据库。您想担心MySQL的DATETIME值之间的差异以及Oracle如何定义它们吗?即使在不同版本的MySQL中,TIMESTAMPS也具有不同的精度级别。直到最近,MySQL才支持时间戳中的毫秒。没有时区问题。这里有一些关于不同数据类型的时区的见解。但这是常识吗?你的同事会花时间学习吗?另一方面,很难将BigINT更改为java.util.Date。使用BigINT会导致很多时区问题被搁置一旁。无需担心范围或精度。你不必担心未来日期范围会缩短什么(TIMESTAMP只适用于2038年)。第三方工具集成。通过使用整数,第三方工具(例如EclipseLink)与数据库的接口很简单。并非所有第三方工具都会像MySQL一样理解“datetime”。如果您使用这些自定义数据类型,想尝试在Hibernate中确定是否应该使用java.sql.TimeStamp或java.util.Date对象?使用基本数据类型使第三方工具的使用变得微不足道。

这个问题与如何在数据库中存储货币值(即1.99美元)密切相关。你应该使用十进制,还是数据库的货币类型,或者最糟糕的是双精度?由于上面列出的许多相同原因,所有三种选择都很糟糕。解决方案是使用BIGINT将货币的价值存储为美分,然后在向用户显示价值时将美分转换为美元。数据库的工作是存储数据,而不是插入数据。您在数据库(尤其是Oracle)中看到的所有这些花哨的数据类型几乎没有增加任何内容,并使您开始进入供应商锁定状态。

MySQL中的时间戳通常用于跟踪记录的更改,并且经常在每次更改记录时更新。如果要存储特定值,应使用datetime字段。

如果您希望在使用UNIX时间戳或本机MySQL日期时间字段之间做出选择,请使用本机datetime格式。您可以通过这种方式在MySQL中进行计算(“SELECT DATE_ADD(my_datetime,INTERVAL 1 DAY)”),如果您想用PHP对记录进行操作,那么在查询记录时,很容易将值的格式更改为UNIX时间戳(“SELECT UNIX_timestamp(my_datatime)”)。

时间戳数据类型存储日期和时间,但使用UTC格式,而不是像datetime那样使用当前时区格式。当您获取数据时,时间戳再次将其转换为当前时区时间。

所以假设你在美国,从一个时区为美国的服务器获取数据,然后你将根据美国时区获取日期和时间。时间戳数据类型列总是在其行更新时自动更新。因此,跟踪上次更新特定行的时间可能很有用。

有关更多详细信息,您可以阅读博客文章Timestamp Vs Datetime。