tl; dr. Sử dụng microtime (false) và lưu trữ kết quả trong MySQL bigint dưới dạng phần triệu giây. Nếu không, bạn phải học tất cả về số học dấu phẩy động, đây là một điều khó hiểu.
Hàm microtime PHP lấy dấu thời gian Unix (hiện tại khoảng hex 50eb7c00 hoặc số thập phân 1,357.609,984) từ một lệnh gọi hệ thống và thời gian micro giây từ lệnh gọi hệ thống khác. Sau đó, nó biến chúng thành một chuỗi ký tự. Sau đó, nếu bạn gọi nó bằng (true), nó sẽ chuyển đổi số đó thành số dấu phẩy động 64-bit IEEE 745, một thứ mà PHP gọi là float
.
Kể từ hôm nay, bạn cần mười chữ số thập phân ở bên trái dấu thập phân để lưu trữ một dấu thời gian UNIX số nguyên. Điều đó sẽ vẫn đúng cho đến khoảng năm 2280 CN khi con cháu của bạn sẽ bắt đầu cần đến mười một chữ số. Bạn sẽ cần sáu chữ số ở bên phải của vị trí thập phân để lưu trữ micro giây.
Bạn sẽ không nhận được tổng độ chính xác đến từng micro giây. Hầu hết các hệ thống giữ xung nhịp hệ thống phụ giây của chúng với độ phân giải của một thứ gì đó trong khoảng 1-33 mili giây. Nó phụ thuộc vào hệ thống.
MySQL phiên bản 5.6.4 trở lên cho phép bạn chỉ định DATETIME(6)
cột, sẽ chứa ngày và giờ ở độ phân giải micro giây. Nếu bạn đang sử dụng phiên bản MySQL như vậy thì đó là cách tuyệt đối.
Trước phiên bản 5.6.4, bạn cần sử dụng MySQL DOUBLE
(IEEE 754 dấu chấm động 64-bit) để lưu trữ các số này. MySQL FLOAT
(Dấu phẩy động 32-bit IEEE 754) không có đủ bit trong định trị của nó để lưu trữ ngay cả thời gian UNIX hiện tại tính bằng giây một cách hoàn toàn chính xác.
Tại sao bạn lưu trữ những dấu thời gian này? Bạn có hy vọng làm được không
WHERE table.timestamp = 1357609984.100000
hoặc các truy vấn tương tự để tra cứu các mặt hàng cụ thể? Điều đó sẽ gặp nguy hiểm nếu bạn sử dụng số thực hoặc số kép ở bất kỳ đâu trong chuỗi xử lý của mình (nghĩa là, ngay cả khi bạn sử dụng microtime(true)
dù chỉ một lần). Họ nổi tiếng là không bình đẳng ngay cả khi bạn nghĩ họ nên làm như vậy. Thay vào đó bạn cần phải sử dụng một cái gì đó như thế này. 0.001
ì được gọi là "epsilon" trong thương mại xử lý số.
WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
AND 1357609984.100000 + 0.001
hoặc một cái gì đó tương tự. Bạn sẽ không gặp sự cố này nếu bạn lưu trữ các dấu thời gian này dưới dạng số thập phân hoặc ở phần triệu giây trong bigint
cột.
Dấu phẩy động 64-bit IEEE có 53 bit định trị - độ chính xác. Dấu thời gian UNIX Epoch hiện tại (giây kể từ ngày 1 tháng 1 năm 1970 00:00Z) lần một triệu sử dụng 51 bit. Vì vậy, không có nhiều độ chính xác trong DOUBLE nếu chúng ta quan tâm đến bit bậc thấp. Mặt khác, độ chính xác sẽ không hết trong vài thế kỷ.
Bạn đang ở gần hết độ chính xác với int64 (BIGINT). Nếu tôi thực sự đang lưu trữ các dấu thời gian micro giây chỉ để sắp xếp chúng trong MySQL, tôi sẽ sử dụng DATETIME(6)
bởi vì tôi sẽ nhận được rất nhiều số học ngày tháng miễn phí. Nếu tôi đang thực hiện một ứng dụng dung lượng lớn trong bộ nhớ, tôi sẽ sử dụng int64.