Znacznik czasu z dokładnością do milisekundy: jak zapisać je w MySQL

83

Muszę opracować aplikację przy użyciu MySQL i zapisać wartości takie jak „1412792828893”, które reprezentują znacznik czasu, ale z dokładnością do milisekundy. To znaczy ilość milisekund od 1.1.1970. Deklaruję wiersz jako, timestampale niestety to nie zadziałało. Wszystkie wartości są ustawione na0000-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`)
) ;

Jak powinna wyglądać deklaracja, aby móc zapisywać wartości znaczników czasu z taką dokładnością?

Luixv
źródło
Jaka wersja MySQL?
Truskawka
mysql Ver 14.14 Distrib 5.6.11, dla Win32 (x86)
Luixv
Wygląda na to, że masz szczęście.
Truskawka
Czy masz pod ręką wartości w milisekundach przed wstawieniem? Jeśli tak, dlaczego nie przechowywać bezpośrednio jako BIGINT?
Sandman,

Odpowiedzi:

139

Musisz być w MySQL w wersji 5.6.4 lub nowszej, aby zadeklarować kolumny z typami danych ułamkowymi sekundami. Nie jesteś pewien, czy masz odpowiednią wersję? Spróbuj SELECT NOW(3). Jeśli pojawi się błąd, oznacza to, że nie masz odpowiedniej wersji.

Na przykład, DATETIME(3)da ci rozdzielczość milisekundową w twoich znacznikach czasu i TIMESTAMP(6)da ci rozdzielczość mikrosekundową na znaczniku czasu w stylu * nix.

Przeczytaj to: https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html

NOW(3) poda aktualny czas z systemu operacyjnego serwera MySQL z dokładnością do milisekund.

Jeśli masz pewną liczbę milisekund od epoki Uniksa , spróbuj tego, aby uzyskać wartość DATETIME (3)

FROM_UNIXTIME(ms * 0.001)

Na przykład sygnatury czasowe JavaScript są przedstawiane w milisekundach od czasu wprowadzenia epoki Uniksa .

(Zauważ, że wewnętrzna arytmetyka ułamkowa MySQL, na przykład * 0.001, jest zawsze traktowana jako zmiennoprzecinkowa podwójnej precyzji IEEE754, więc jest mało prawdopodobne, że stracisz precyzję, zanim Słońce stanie się gwiazdą białego karła.)

Jeśli używasz starszej wersji MySQL i potrzebujesz dokładności co do sekundy, najlepszą drogą jest aktualizacja. Cokolwiek innego zmusi Cię do wykonania niechlujnych obejść.

Jeśli z jakiegoś powodu nie możesz uaktualnić, możesz rozważyć użycie kolumn BIGINTlub DOUBLEdo przechowywania znaczników czasu JavaScript tak, jakby były liczbami. FROM_UNIXTIME(col * 0.001)nadal będzie działać OK. Jeśli potrzebujesz aktualnego czasu do przechowywania w takiej kolumnie, możesz użyćUNIX_TIMESTAMP() * 1000

O. Jones
źródło
Zmieniłem moją definicję na timestamp (6), ale kiedy próbuję dodać wartości przy użyciu tej składni INSERT INTO prawdopodobieństwo (zmierzone_at, prawdopodobieństwo, identyfikator_ dostawcy, identyfikator_segmentu) VALUES (1412877161519,0.7418073347680607,1,211623); Nadal otrzymuję 0000-00-00 00: 00: 00.00000 w kolumnie „Measured_at”. Jak wstawić wartości do tej tabeli?
Luixv
1
@Luixv musiałbyś po drodze przeliczyć wartość w: INSERT ... VALUES(FROM_UNIXTIME(0.001 * 1412877161519), 0.7418 ... );
Michael - sqlbot
Mnożenie przez 0,001 ratuje życie! Nigdy bym nie przypuszczał, że zadziała bez utraty drugiej frakcji. Dziękuję Ci.
Pavel S.
W moim przypadku, ponieważ testuję z malinowym pi (a instalacja mysql 5.6w RPI jest naprawdę uciążliwa , zamierzam zapisać informacje jako czas
unixowy
0

Możesz użyć BIGINT w następujący sposób:

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)
   );
M Shafaei N
źródło
Jednak BIGINT ma 8 bajtów. Nie ma nic wydajniejszego? To jakby o dwa bajty więcej na rekord niż potrzebujesz
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');
bien nguyen
źródło