具有毫秒精度的时间戳:如何将它们保存在 MySQL 中
Posted
技术标签:
【中文标题】具有毫秒精度的时间戳:如何将它们保存在 MySQL 中【英文标题】:Timestamp with a millisecond precision: How to save them in MySQL 【发布时间】:2014-12-05 14:34:28 【问题描述】:我必须使用 mysql 开发应用程序,并且必须保存诸如“1412792828893”之类的值,这些值表示时间戳,但精度为毫秒。也就是说,自 1.1.1970 以来的毫秒数。我将该行声明为timestamp
,但不幸的是这不起作用。所有值都设置为0000-00-00 00:00:00
CREATE TABLE IF NOT EXISTS `probability` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`segment_id` int(11) NOT NULL,
`probability` float NOT NULL,
`measured_at` timestamp NOT NULL,
`provider_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ;
应该如何声明才能以这种精度保存时间戳值?
【问题讨论】:
什么版本的 MySQL? mysql Ver 14.14 Distrib 5.6.11,适用于 Win32 (x86) 看来你很幸运。 您手头有插入前几毫秒的值吗?如果是这样,为什么不直接存储为 BIGINT? 【参考方案1】:您需要使用 MySQL 5.6.4 或更高版本才能声明具有小数秒时间数据类型的列。不确定您的版本是否正确?试试SELECT NOW(3)
。如果出现错误,则说明版本不正确。
例如,DATETIME(3)
将为您的时间戳提供毫秒分辨率,TIMESTAMP(6)
将为您提供 *nix 样式时间戳的微秒分辨率。
阅读:https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html
NOW(3)
将为您提供 MySQL 服务器操作系统的当前时间,精度为毫秒。
如果自 Unix epoch 之后的毫秒数,请尝试此操作以获取 DATETIME(3) 值
FROM_UNIXTIME(ms * 0.001)
例如,javascript timestamps 以自Unix epoch 起的毫秒数表示。
(请注意,MySQL 内部的小数运算,如 * 0.001
,始终作为 IEEE754 双精度浮点数处理,因此在太阳变成白矮星之前您不太可能失去精度。)
如果您使用的是旧版本的 MySQL,并且需要亚秒级时间精度,那么最好的方法是升级。其他任何事情都会迫使您做出混乱的解决方法。
如果由于某种原因无法升级,您可以考虑使用 BIGINT
或 DOUBLE
列来存储 Javascript 时间戳,就像它们是数字一样。 FROM_UNIXTIME(col * 0.001)
仍然可以正常工作。如果您需要将当前时间存储在这样的列中,您可以使用UNIX_TIMESTAMP() * 1000
【讨论】:
我已将我的定义更改为 timestamp(6),但尝试使用此语法添加值时 INSERT INTO probability (measured_at,probability,provider_id,segment_id) VALUES(1412877161519,0.7418073347680607,1,211623) ;我仍然在“measured_at”列中得到 0000-00-00 00:00:00.00000。我应该如何向这个表中插入值? @Luixv 您需要在输入过程中转换值:INSERT ... VALUES(FROM_UNIXTIME(0.001 * 1412877161519), 0.7418 ... );
乘以 0.001 是救命稻草!我永远无法猜到它会在不丢失第二个分数的情况下起作用。谢谢。
就我而言,因为我正在使用树莓派进行测试(在 RPI 中安装 mysql 5.6
确实很麻烦,所以我将信息保存为 unix 时间。跨度>
【参考方案2】:
CREATE TABLE fractest( c1 TIME(3), c2 DATETIME(3), c3 TIMESTAMP(3) );
INSERT INTO fractest VALUES
('17:51:04.777', '2018-09-08 17:51:04.777', '2018-09-08 17:51:04.777');
【讨论】:
【参考方案3】:请通过同样提及时间戳timestamp(2)
或timestamp(3)
或timestamp(5)
的长度(长度可以是您想要的以毫秒为单位的任何位数)来创建这样的表。 Mysql 版本应为 5.6 或以上。
https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
CREATE TABLE IF NOT EXISTS `probability` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`measured_at` timestamp(2) NOT NULL,
PRIMARY KEY (`id`)
) ;
然后通过 Java 传递时间戳。
statement.setTimestamp(2, new Timestamp(new Date().getTime()))
【讨论】:
【参考方案4】:您可以按如下方式使用 BIGINT:
CREATE TABLE user_reg (
user_id INT NOT NULL AUTO_INCREMENT,
identifier INT,
phone_number CHAR(11) NOT NULL,
verified TINYINT UNSIGNED NOT NULL,
reg_time BIGINT,
last_active_time BIGINT,
PRIMARY KEY (user_id),
INDEX (phone_number, user_id, identifier)
);
【讨论】:
BIGINT 是 8 个字节。没有比这更有效的了吗?这就像每条记录比您需要的多两个字节以上是关于具有毫秒精度的时间戳:如何将它们保存在 MySQL 中的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Redshift 中将时间戳(具有毫秒)转换为 EPOCH