微量时间的DECIMAL长度(真)?

时间:2013-01-07 23:54:29

标签: php mysql decimal maxlength microtime

我想将PHP的microtime存储为MySQL中的时间戳。

我一直told最好将它存储在DECIMAL中,但我找不到理想的尺寸。

有谁知道最大大小microtime(true)返回什么,所以我可以把它作为我的数据类型长度?

我应该选择变量DECIMAL长度吗?

4 个答案:

答案 0 :(得分:14)

TL;博士。使用microtime(false)并将结果存储在MySQL bigint中,以百万分之一秒为单位。否则你必须学习浮点运算,这是一个很大的毛球。

PHP microtime函数从一次系统调用中获取Unix时间戳(当前约为十六进制50eb7c00或十进制1,357,609,984),以及另一次系统调用的微秒时间。然后它将它们变成一个字符串。然后,如果你用(true)调用它,它将该数字转换为64位IEEE 745浮点数,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

或类似查询以查找特定项目?如果你在处理链的任何地方使用浮点数或双数字(即使你曾经使用microtime(true)一次),那就充满了危险。即使你认为应该这样做,他们也因为不平等而臭名昭着。相反,你需要使用这样的东西。 0.001在数字处理行业中被称为“epsilon”。

  WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
                            AND 1357609984.100000 + 0.001

或类似的东西。如果将这些时间戳存储为bigint列中的小数或百万分之一秒,则不会出现此问题。

IEEE 64位浮点有53位尾数 - 精度。当前的UNIX Epoch时间戳(自1970年1月1日 - 00:00Z以来的秒)乘以100位使用51位。因此,如果我们关心低阶位,那么DOUBLE中没有太多额外的精度。另一方面,精度不会耗尽几个世纪。

使用int64(BIGINT),你的精度已经差一点了。如果我实际上只是为了在MySQL中对它们进行排序来存储微秒时间戳,我会选择DATETIME(6),因为我会免费获得大量的日期算术。如果我正在使用内存大批量应用,我会使用int64。

答案 1 :(得分:1)

这取决于您需要的精度。如果毫秒足够您,并且您不希望任何大于999999秒的运行时间,则可以使用DECIMAL(10,4)。你可以通过这种方式满足你的需求。

关于理论最大值,它受系统中float的大小限制(32位,64位)。有关详细信息,请参阅PHP Float。但正如我所说,这是理论上的。没有计时器会给你精确的时间。

答案 2 :(得分:1)

在MySQL 5.6.4及更高版本中,the native DATETIME and TIMESTAMP types can support fractional seconds。因此,您可以在DATETIME(6)TIMESTAMP(6)列中存储微秒分辨率的时间戳。

要将PHP microtime()返回值转换为MySQL日期时间格式,您可以使用MySQL FROM_UNIXTIME()函数,或者,如果您使用的是PHP DateTime类,则DateTime::format()。请注意,PHP date()函数目前支持微秒时间戳。 (它确实有一个微秒的格式代码u,但它始终将其映射到000000。)

对于较旧的MySQL版本,它们无法在其原生日期时间类型中存储微秒,您应该使用DOUBLEBIGINT(以微秒表示的值,即乘以1,000,000)或{{1 (这应该足够几百年了)。

答案 3 :(得分:-1)

为什么不将它存储为float?这就是microtime(true)返回的内容,因此它是最佳候选者。