3

我不想再开始讨论使用DATETIMEvs TIMESTAMPvs之间的赞成或反对INT。(我已经阅读过使用 MySQL 的 TIMESTAMP 与直接存储时间戳之类的文章。)

我有时使用INT数据类型将 unix 时间戳存储在数据库中。这是因为我的应用程序中的日期和时间计算通常使用 unix 时间戳完成(例如会话超时和令牌到期)。DATETIME此外,当我可以WHERE简单地比较子句中的整数值时,数据库中的数据选择比使用更快。很少有表有 10+ 百万行(最多 1 亿行),这 4 个字节也真正节省了存储空间(在磁盘和内存中,因为索引更小)。

关于 Y2K38 问题,我假设(并希望如此),UNIX_TIMESTAMP在 MySQLtime()中的 PHP 将在未来返回 64 位值,因此无需更改应用程序本身的某些内容。关键是,我在 MySQL 中将所有这些伪整数时间戳存储为无符号整数(我的意思是INT不是BIGINT)。当然,无符号整数时间戳会在 2106 年溢出,但这比 2038 年要多一点时间。

我现在的问题是:假设它UNIX_TIMESTAMP本身将在 2038 年之后工作,那么在 2106 年之前,当这些时间戳在 MySQL 中存储为无符号整数时,MySQL 和/或 PHP 中是否存在任何问题?(请不要争论:到2038年之前会有很多时间来解决这个问题,我想从不再触及应用程序的角度来澄清这一点)

编辑:因为问题出现了:我只在这些列中存储当前时间戳,没有出生日期,没有未来日期。只有当前的时间戳,所以我想澄清这是否会在 2038 年之后起作用。

4

1 回答 1

1

您对 UNIX_TIMESTAMP() 的假设是一个很大的假设。

目前,如果您尝试,UNIX_TIMESTAMP 返回 0

mysql> select unix_timestamp("2038-01-19" );
+-------------------------------+
| unix_timestamp("2038-01-19" ) |
+-------------------------------+
|                    2147468400 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select unix_timestamp("2038-01-20");
+------------------------------+
| unix_timestamp("2038-01-20") |
+------------------------------+
|                            0 |
+------------------------------+
1 row in set (0.00 sec)

虽然存储长度超过 32 位的 INT 会起作用,但除非您对 unix_timestamp(int64) 的实现如何工作有所了解,否则问题实际上更多的是猜测而不是事实。

这意味着您所做的任何整数运算对于 64 位整数仍然有效,因此对于查找过期会话(时间戳 + 超时 <(自 1970 年以来的 64 位秒数))仍然有效。您是否可以依赖 from_unixtime() 和 unix_timestamp() 函数取决于解决方案是否只是将赌注提高到 64 位,或者未来 20 多年的整个世界是否决定设置一个新纪元。

没有人确切知道。

于 2013-08-28T12:15:13.280 回答