Zeitstempel mit Millisekundengenauigkeit: So speichern Sie sie in MySQL


81

Ich muss eine Anwendung mit MySQL entwickeln und Werte wie "1412792828893" speichern, die einen Zeitstempel darstellen, jedoch mit einer Genauigkeit von einer Millisekunde. Das heißt, die Anzahl der Millisekunden seit dem 1.1.1970. Ich erkläre die Zeile als timestampaber leider hat das nicht funktioniert. Alle Werte sind auf eingestellt0000-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`)
) ;

Wie sollte die Deklaration sein, um Zeitstempelwerte mit dieser Genauigkeit speichern zu können?


Welche Version von MySQL?
Erdbeere

MySQL Ver 14.14 Distrib 5.6.11, für Win32 (x86)
Luixv

Sieht so aus, als hättest du Glück.
Erdbeere

Haben Sie die Werte als Millisekunden vor dem Einfügen zur Hand? Wenn ja, warum nicht direkt als BIGINT speichern?
Sandman

Antworten:


137

Sie müssen sich in MySQL Version 5.6.4 oder höher befinden, um Spalten mit Datentypen in Sekundenbruchteilen deklarieren zu können. Sie sind sich nicht sicher, ob Sie die richtige Version haben? Versuchen Sie es SELECT NOW(3). Wenn Sie eine Fehlermeldung erhalten, haben Sie nicht die richtige Version.

Sie erhalten beispielsweise DATETIME(3)eine Millisekundenauflösung in Ihren Zeitstempeln und TIMESTAMP(6)eine Mikrosekundenauflösung für einen Zeitstempel im * nix-Stil.

Lesen Sie dies: https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html

NOW(3) Sie erhalten die aktuelle Zeit vom Betriebssystem Ihres MySQL-Servers mit Millisekundengenauigkeit.

Wenn Sie seit der Unix-Epoche einige Millisekunden Zeit haben , versuchen Sie dies, um einen DATETIME (3) -Wert zu erhalten

FROM_UNIXTIME(ms * 0.001)

Javascript-Zeitstempel werden beispielsweise seit der Unix-Epoche in Millisekunden dargestellt .

(Beachten Sie, dass die interne gebrochene MySQL- * 0.001Brucharithmetik immer als Gleitkomma mit doppelter Genauigkeit nach IEEE754 behandelt wird. Daher ist es unwahrscheinlich, dass Sie an Genauigkeit verlieren, bevor die Sonne zu einem weißen Zwergstern wird.)

Wenn Sie eine ältere Version von MySQL verwenden und eine Zeitgenauigkeit von weniger als einer Sekunde benötigen, ist ein Upgrade der beste Weg. Alles andere zwingt Sie dazu, unordentliche Problemumgehungen durchzuführen.

Wenn Sie aus irgendeinem Grund kein Upgrade durchführen können, können Sie in Betracht ziehen, BIGINToder DOUBLESpalten zum Speichern von Javascript-Zeitstempeln zu verwenden, als wären sie Zahlen. FROM_UNIXTIME(col * 0.001)wird immer noch OK funktionieren. Wenn Sie die aktuelle Zeit zum Speichern in einer solchen Spalte benötigen, können Sie diese verwendenUNIX_TIMESTAMP() * 1000


Ich habe meine Definition in Zeitstempel (6) geändert, aber beim Versuch, Werte mit dieser Syntax hinzuzufügen, INSERT INTO Wahrscheinlichkeit (Measured_at, Wahrscheinlichkeit, Provider_ID, Segment_ID) VALUES (1412877161519,0.7418073347680607,1,211623); Ich erhalte immer noch 0000-00-00 00: 00: 00.00000 in der Spalte "Measured_at". Wie soll ich Werte in diese Tabelle einfügen?
Luixv

1
@Luixv müssten Sie den Wert auf dem Weg in konvertieren: INSERT ... VALUES(FROM_UNIXTIME(0.001 * 1412877161519), 0.7418 ... );
Michael - sqlbot

Das Multiplizieren mit 0,001 ist ein Lebensretter! Ich könnte nie ahnen, dass es funktionieren würde, ohne den zweiten Bruchteil zu verlieren. Vielen Dank.
Pavel S.

In meinem Fall, da ich mit einem Himbeer-Pi teste (und es wirklich umständlich ist, mysql 5.6im RPI zu installieren , werde ich die Informationen als Unix-Zeit
speichern

0

Sie können BIGINT wie folgt verwenden:

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

Ein BIGINT besteht jedoch aus 8 Bytes. Gibt es nichts effizienter? Das sind zwei Bytes mehr pro Datensatz als Sie benötigen
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');
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.