Dấu thời gian với độ chính xác mili giây: Cách lưu chúng trong MySQL


81

Tôi phải phát triển một ứng dụng bằng MySQL và tôi phải lưu các giá trị như "1412792828893" đại diện cho một dấu thời gian nhưng có độ chính xác là một phần nghìn giây. Tức là lượng mili giây kể từ 1.1.1970. Tôi khai báo hàng là timestampnhưng rất tiếc điều này không hoạt động. Tất cả các giá trị được đặt thành0000-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`)
) ;

Khai báo phải như thế nào để có thể lưu các giá trị dấu thời gian với độ chính xác này?


Phiên bản MySQL nào?
Strawberry

mysql Ver 14,14 distrib 5.6.11, cho Win32 (x86)
Luixv

Có vẻ như bạn đang gặp may mắn.
Strawberry

Bạn có sẵn các giá trị dưới dạng mili giây trước khi chèn không? Nếu vậy, tại sao không lưu trữ trực tiếp như BIGINT?
Sandman,

Câu trả lời:


136

Bạn cần ở MySQL phiên bản 5.6.4 trở lên để khai báo các cột có kiểu dữ liệu thời gian phân số-giây. Không chắc bạn có phiên bản phù hợp? Cố gắng SELECT NOW(3). Nếu bạn gặp lỗi, bạn không có phiên bản phù hợp.

Ví dụ: DATETIME(3)sẽ cung cấp cho bạn độ phân giải mili giây trong dấu thời gian của bạn và TIMESTAMP(6)sẽ cung cấp cho bạn độ phân giải micro giây trên dấu thời gian kiểu * nix.

Đọc phần này: https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html

NOW(3) sẽ cung cấp cho bạn thời gian hiện tại từ hệ điều hành máy chủ MySQL của bạn với độ chính xác mili giây.

Nếu bạn có số mili giây kể từ kỷ nguyên Unix , hãy thử điều này để nhận giá trị DATETIME (3)

FROM_UNIXTIME(ms * 0.001)

Ví dụ: dấu thời gian Javascript được biểu thị bằng mili giây kể từ kỷ nguyên Unix .

(Lưu ý rằng số học phân số nội bộ của MySQL, giống như * 0.001, luôn được xử lý dưới dạng dấu chấm động chính xác kép IEEE754, vì vậy, không chắc bạn sẽ mất độ chính xác trước khi Mặt trời trở thành một ngôi sao lùn trắng.)

Nếu bạn đang sử dụng phiên bản MySQL cũ hơn và bạn cần độ chính xác của thời gian dưới giây, thì cách tốt nhất của bạn là nâng cấp. Bất cứ điều gì khác sẽ buộc bạn phải thực hiện các cách giải quyết lộn xộn.

Nếu vì lý do nào đó mà bạn không thể nâng cấp, bạn có thể cân nhắc sử dụng BIGINThoặc DOUBLEcác cột để lưu trữ dấu thời gian Javascript như thể chúng là số. FROM_UNIXTIME(col * 0.001)sẽ vẫn hoạt động OK. Nếu bạn cần thời gian hiện tại để lưu trữ trong một cột như vậy, bạn có thể sử dụngUNIX_TIMESTAMP() * 1000


Tôi đã thay đổi định nghĩa của mình thành dấu thời gian (6) nhưng khi cố gắng thêm các giá trị bằng cú pháp này CHÈN VÀO xác suất (đo_at, xác suất, nhà cung cấp_id, phân_cấp) VALUES (1412877161519,0.7418073347680607,1,211623); Tôi vẫn nhận được 0000-00-00 00: 00: 00.00000 tại cột "Measure_at". Tôi nên chèn giá trị vào bảng này như thế nào?
Luixv

1
@Luixv bạn sẽ cần phải chuyển đổi các giá trị trên đường trong: INSERT ... VALUES(FROM_UNIXTIME(0.001 * 1412877161519), 0.7418 ... );
Michael - sqlbot

Nhân với 0,001 là một cứu cánh! Tôi không bao giờ có thể đoán nó sẽ hoạt động mà không mất phần thứ hai. Cảm ơn bạn.
Pavel S.

Trong trường hợp của tôi, vì tôi đang thử nghiệm với raspberry pi (và việc cài đặt mysql 5.6trong RPI thực sự phức tạp , tôi sẽ lưu thông tin dưới dạng thời gian unix.
silgon

0

Bạn có thể sử dụng BIGINT như sau:

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

Tuy nhiên, một BIGINT là 8 byte. Không có gì hiệu quả hơn? Điều đó giống như nhiều hơn hai byte cho mỗi bản ghi so với mức bạn cần
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');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.