MySQL NOW()函数具有高精度

时间:2012-01-23 22:29:51

标签: mysql

我正在研究一种通过远程MySQL数据库存储数据的C ++应用程序。

其中一项功能是尽可能保持与远程数据保持同步。为了实现这一点,我使用NOW()函数来获取最后的更新时间,并且在更新记录时,将last_changed字段设置为NOW()。

现在这种方法很好,除了最大精度高达一秒的问题。导致数十个重复条目,这会浪费带宽,并且必须手动删除它们。

为了限制大部分膨胀,我希望精度大于此值,最好是高达微秒(如unix gettimeofday())。但是,我在文档中找不到任何有关此内容的信息。我能找到的是NOW()函数使用的是一个变量类型,能够存储高达微秒的精度(source)。但是在使用它时,第二个之后的所有精度都是零。

有没有办法强制Mysql服务器使用更高精度的计时器(并将潜在的性能视为理所当然)?还是另一种方法来实现这个目标?

5 个答案:

答案 0 :(得分:7)

在MariaDB中,您可以使用

SELECT NOW(4);

获取时间戳中的milisecs。请参阅here

答案 1 :(得分:5)

http://dev.mysql.com/doc/refman/5.1/en/datetime.html

DATETIME或TIMESTAMP值可以包括最小微秒(6位)精度的尾随小数秒部分。 虽然可以识别此小数部分,但会从存储在DATETIME或TIMESTAMP列中的值中将其丢弃。

使用varchar或text列来保留分数。

ps:MySQL本身无法获得微秒的时间

pps:未来版本除外)) http://dev.mysql.com/doc/refman/5.6/en/news-5-6-4.html

  

MySQL现在允许TIME,DATETIME和TIMESTAMP的小数秒   值,精度高达微秒(6位)。定义一个   包含小数秒部分的列,请使用语法   type_name(fsp),其中type_name是TIME,DATETIME或TIMESTAMP,以及   fsp是小数秒精度。

     

某些表达式产生的结果与以前的结果不同。   示例:timestamp系统变量返回包含的值   一个微秒的小数部分而不是整数值。

答案 2 :(得分:4)

因此,在提示之后查看MySQL用户定义的函数,我能够使其工作。

在Code :: Blocks中我编写了这个简单的库文件

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef long long longlong;    
#include <mysql.h>
#include <ctype.h>    
#include <sys/time.h>
#include <unistd.h>
static pthread_mutex_t LOCK_hostname;
extern "C" longlong PreciseNow(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
extern "C" my_bool PreciseNow_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
extern "C" void PreciseNow_deinit(UDF_INIT *initid);
my_bool PreciseNow_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
 return 0; //optional
}
void PreciseNow_deinit(UDF_INIT *initid)
{ //optional
}

longlong PreciseNow(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
   struct timeval start;
   long mtime, seconds, useconds;
   gettimeofday(&start, NULL);
   return start.tv_sec * 1000000 + start.tv_usec;
}

它唯一能做的就是返回当前的系统时间。我将lib文件放在'/ usr / lib / mysql / plugin /'中。 其次,在数据库中,我执行了以下查询:

  

创建功能PreciseNow RETURNS INTEGER SONAME'libhrt.so'

最后我将timestamp列转换为bigint(8字节整数)。也许这不是必要的,但看到C函数返回相同的对象类型,为什么不...

现在,当运行SQL查询“SELECT PreciseNow()”时,我得到内置“NOW()”的微秒精确版本! 由于我对MySQL的知识非常有限,我认为这是一个完全合法且有效的解决方案吗?

答案 3 :(得分:2)

MySQL将支持微秒,请参阅MySQL 5.6.4 changelog

  

分数秒处理

     

不兼容的变化:MySQL现在允许TIME的小数秒,   DATETIME和TIMESTAMP值,最大为微秒(6位数)   精确。要定义包含小数秒部分的列,   使用语法type_name(fsp),其中type_name是TIME,DATETIME或   TIMESTAMP和fsp是小数秒的精度。例如:

     

创建表t1(t TIME(3),dt DATETIME(6)); fsp值,如果给出,   必须在0到6的范围内。值为0表示没有   分数部分。如果省略,则默认精度为0.(这有所不同   从标准SQL默认值6开始,与之前的兼容性   MySQL版本。)

     

以下各项总结了此更改的含义。看到   第10.3.5节,“时间值的分数秒”。

答案 4 :(得分:1)

扩展amra。在列上设置fsp后,您可以使用MySQL中的内置函数。

现在(6)或CURTIME(6)等。它在MySQL 5.6中得到支持