2038年1月19日03:14:07 GMT现在距离我们不到20年。这就是UNIX的32位时间戳记经过的时间。我正在设计一些当时可能仍在使用的MySQL表。
这是所谓的 2038年问题。
从我在MariaDB 10.3上尝试过的东西看来,使用rm
数据类型在日期翻转之后的日期戳产生错误1292(错误的日期时间值)。
将这些表设计为适合未来的最佳做法是什么?我可以使用TIMESTAMP
数据,但是DATETIME
在时区方面具有一些非常有用的功能。
MySQL的某些将来版本(更不用说Linux和其他UNIX派生版本)是否有可能升级?
答案 0 :(得分:2)
使用BigInts存储Unix时间戳。尽管缺少一些与之相关的糖,但它在功能上等同于TIMESTAMP类型。但是,如果在应用程序级别上您只是乐意使用UNIX时间戳,那么它根本没有任何区别,至少就我而言,至少在偶尔使用UNIX_TIMESTAMP(...)/ FROM_UNIXTIME( …)致电。那将使您远远超过2038年。
尽管我希望MySQL / Maria暴民会在X.y版中创建一些hack,它将自动更新TimeStamp字段,作为升级路径的一部分。请注意,它可能会在2038年1月18日发布。 ;)
无论如何,如果您想将来证明,将BIGINT视为UNIX时间戳就是您的答案。
答案 1 :(得分:0)
提取出您在1998年编写的代码。找到一台运行它的机器。您可能需要找到一个软盘驱动器才能加载它。
现在,问问自己“ 20年后代码和硬件会发生什么”?
我建议,除了政府合同外,2018年编写的所有代码都将在2038年之前丢进垃圾桶。
1998年,MySQL运行版本3.xx;我不想用10年(或20年)的杆来触碰它。此后,DATETIME
的内部格式发生了变化,添加了CHARACTER SETs
,添加了许多优化,添加了子查询,修复了错误,等等。
我在最后一段中的意思是,随着MySQL在未来20年的成熟,您今天编写的任何内容都将发生 application 更改。解决2038问题的方法仅仅是众多更改之一。
答案 2 :(得分:0)
使用这两个函数并将时间戳存储为十进制
CREATE FUNCTION from_unixtime_fixed (v DECIMAL(16,6))
RETURNS DATETIME(6) DETERMINISTIC
RETURN DATE_ADD(FROM_UNIXTIME(0), INTERVAL v second);
CREATE FUNCTION unix_timestamp_fixed (v DATETIME(6))
RETURNS DECIMAL(16,6) DETERMINISTIC
RETURN TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(0), v);
示例用法: 选择 unix_timestamp_fixed('2039-01-01');
返回 2177449200.000000
select from_unixtime_fixed(2177449200.100000);
返回 2039-01-01 00:00:00.100000
如果您对毫秒不感兴趣,请将 DECIMAL(16,6) 减少到 DECIMAL(16,0)