我想将 PHP 的微时间存储为我在 MySQL 中的时间戳。
我去过told最好用 DECIMAL
存储它,但我找不到理想的大小。
有谁知道 microtime(true)
返回的最大大小是多少,所以我可以把它作为我的数据类型长度?
我应该选择可变的 DECIMAL
长度吗?
最佳答案
tl;博士。使用 microtime(false) 并将结果以百万分之一秒的形式存储在 MySQL bigint 中。否则你必须学习浮点运算,这是一个大毛球。
PHP microtime 函数从一个系统调用中获取 Unix 时间戳(当前约为十六进制 50eb7c00 或十进制 1,357,609,984),并从另一个系统调用中获取微秒时间。然后它把它们变成一个字符串。然后,如果你用 (true) 调用它,它会将该数字转换为 64 位 IEEE 745 float ,PHP 称之为 float
。
从今天开始,您需要小数点左侧的十位小数来存储整数 UNIX 时间戳。直到大约公元 2280 年,你的后代将开始需要 11 位数字时,这种情况才会发生。您需要小数点右侧的六位数字来存储微秒。
您不会获得总微秒精度。大多数系统将其亚秒级系统时钟的分辨率保持在 1-33 毫秒的范围内。这取决于系统。
MySQL 版本 5.6.4 及更高版本允许您指定 DATETIME(6)
列,它将日期和时间保存到微秒分辨率。如果您使用的是这样的 MySQL 版本,那绝对是正确的选择。
在 5.6.4 版本之前,您需要使用 MySQL DOUBLE
(IEEE 754 64 位浮点)来存储这些数字。 MySQL FLOAT
(IEEE 754 32 位浮点)的尾数中没有足够的位来完全准确地存储当前的 UNIX 时间(以秒为单位)。
为什么要存储这些时间戳?你希望这样做吗
WHERE table.timestamp = 1357609984.100000
或类似的查询来查找特定项目?如果您在处理链中的任何位置使用 float 或 double (即,即使您使用 microtime(true)
一次),这将充满危险。他们臭名昭著,即使你认为他们应该平等。相反,您需要使用类似的东西。 0.001
在数值加工行业中被称为“epsilon”。
WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
AND 1357609984.100000 + 0.001
或类似的东西。如果将这些时间戳以小数或百万分之一秒的形式存储在 bigint
列中,则不会出现此问题。
IEEE 64 位浮点有 53 位尾数——精度。当前的 UNIX 纪元时间戳(自 1970 年 1 月 1 日 00:00Z 以来的秒数)乘以一百万使用 51 位。因此,如果我们关心低位,则 DOUBLE 没有太多额外的精度。另一方面,精度不会在几个世纪内耗尽。
使用 int64(BIGINT) 的精度还远远不够。如果我实际上只是为了在 MySQL 中对它们进行排序而存储微秒时间戳,我会选择 DATETIME(6)
因为我会免费获得很多日期算术。如果我正在做一个内存大容量应用程序,我会使用 int64。
关于php - 微时间的十进制长度(真)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14206159/