Marca de tiempo con una precisión de milisegundos: cómo guardarlos en MySQL


81

Tengo que desarrollar una aplicación usando MySQL y tengo que guardar valores como "1412792828893" que representan una marca de tiempo pero con una precisión de un milisegundo. Es decir, la cantidad de milisegundos desde el 1.1.1970. Declaro la fila como, timestamppero desafortunadamente esto no funcionó. Todos los valores se establecen en0000-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`)
) ;

¿Cómo debería ser la declaración para poder guardar valores de marca de tiempo con esta precisión?


¿Qué versión de MySQL?
Fresa

mysql Ver 14.14 Distrib 5.6.11, para Win32 (x86)
Luixv

Parece que estás de suerte.
Fresa

¿Tiene los valores en la mano como milisegundos antes de la inserción? Si es así, ¿por qué no almacenar directamente como BIGINT?
Sandman

Respuestas:


136

Debe tener la versión 5.6.4 de MySQL o posterior para declarar columnas con tipos de datos de una fracción de segundo. ¿No estás seguro de tener la versión correcta? Prueba SELECT NOW(3). Si recibe un error, no tiene la versión correcta.

Por ejemplo, DATETIME(3)le dará una resolución de milisegundos en sus marcas de tiempo y TIMESTAMP(6)le dará una resolución de microsegundos en una marca de tiempo de estilo * nix.

Lea esto: https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html

NOW(3) le dará la hora actual del sistema operativo de su servidor MySQL con precisión de milisegundos.

Si tiene varios milisegundos desde la época de Unix , intente esto para obtener un valor DATETIME (3)

FROM_UNIXTIME(ms * 0.001)

Las marcas de tiempo de Javascript , por ejemplo, se representan en milisegundos desde la época de Unix .

(Tenga en cuenta que la aritmética fraccionaria interna de MySQL, como * 0.001, siempre se maneja como punto flotante de doble precisión IEEE754, por lo que es poco probable que pierda precisión antes de que el Sol se convierta en una estrella enana blanca).

Si está utilizando una versión anterior de MySQL y necesita una precisión de tiempo inferior a un segundo, su mejor camino es actualizar. Cualquier otra cosa te obligará a hacer soluciones complicadas.

Si, por alguna razón, no puede actualizar, podría considerar usar columnas BIGINTo DOUBLEpara almacenar marcas de tiempo de Javascript como si fueran números. FROM_UNIXTIME(col * 0.001)seguirá funcionando bien. Si necesita la hora actual para almacenar en dicha columna, puede usarUNIX_TIMESTAMP() * 1000


Cambié mi definición a la marca de tiempo (6) pero cuando intento agregar valores usando esta sintaxis INSERT INTO Probabilidad (Measured_at, Probability, Provider_id, Segment_id) VALUES (1412877161519,0.7418073347680607,1,211623); Todavía obtengo 0000-00-00 00: 00: 00.00000 en la columna "Measured_at". ¿Cómo debo insertar valores en esta tabla?
Luixv

1
@Luixv necesitaría convertir el valor en el camino en: INSERT ... VALUES(FROM_UNIXTIME(0.001 * 1412877161519), 0.7418 ... );
Michael - sqlbot

¡Multiplicar por 0,001 es un salvavidas! Nunca podría adivinar que funcionaría sin perder una segunda fracción. Gracias.
Pavel S.

En mi caso, dado que estoy probando con una raspberry pi (y es realmente engorroso de instalar mysql 5.6en el RPI, voy a guardar la información como tiempo Unix.)
silgon

0

Puede utilizar BIGINT de la siguiente manera:

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)
   );

Sin embargo, un BIGINT tiene 8 bytes. ¿No hay nada más eficiente? Eso es como dos bytes más por registro de los que necesita
S. Imp

0
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');
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.