2014-09-18 179 views
3

我有一个持续的过程,它检查数据库表中的一行,并根据子进程最后一次产生的时间(基本上,一个非常简单的CRON替换)在某个时间间隔产生子进程。减去时间戳差异

我最初实现它,只是从存储在last_start列中的值中减去当前时间戳。 CURRENT_TIMESTAMP - last_start。这似乎工作,但更仔细的检查显示时间戳扣除行为相当奇怪。

看起来,当我们越过分钟屏障(所以,当前时间点到一分钟),计算出的“差异”将跳跃40(例如从59增加到100)。这个看起来像像“1:00” - 类型 - 直到我们达到如下所示的状态,其中“秒”部分超过60(在下面的示例中为95)。

我解决了这个问题,通过使用TIMESTAMPDIFF方法来做减法(谢谢Stack Overflow!)。但是,我不清楚为什么这首先失败了。

mysql db_name -e 'select CURRENT_TIMESTAMP, last_start, CURRENT_TIMESTAMP - last_start , TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) from tasks where id = 3'  Thu Sep 11 09:49:17 2014 

CURRENT_TIMESTAMP  last_start    CURRENT_TIMESTAMP - last_start  TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) 
2014-09-11 09:49:17  2014-09-11 09:37:22 1195         715 

任何人都可以向我解释什么时候我刚刚减去时间戳,因为我在做什么?

编辑:表架构如下:

CREATE TABLE `tasks` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `task` char(128) NOT NULL, 
    `run_count` int(10) unsigned NOT NULL DEFAULT '0', 
    `domina` char(128) DEFAULT NULL, 
    `slave` char(128) DEFAULT NULL, 
    `last_start` timestamp NULL DEFAULT NULL, 
    `last_end` timestamp NULL DEFAULT NULL, 
    `avg_duration` int(10) unsigned NOT NULL DEFAULT '0', 
    `last_status` char(64) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 
+0

'last_start'的数据类型是什么?处理未存储在本机类型中的日期和时间时,MySQL可能会很时髦。 – 2014-09-18 20:00:49

+0

添加了create table语句 – v4nz 2014-09-18 20:11:29

+1

使用'timestampdiff()'而不是'-'。 '-'将参数视为整数,这会导致您的问题。 – 2014-09-18 20:12:54

回答

2

为什么这个问题呢?那么,你会期望一个名为TIMESTAMP的数据类型的数据库(或任何其他软件产品)和一个名为CURRENT_TIMESTAMP的“常量”将代表后者使用前者。

但是没有。这不是MySQL。 CURRENT_TIMESTAMPnow()的同义词,其类型与上下文相关。令人高兴的是,文档解释这个很清楚:

返回当前日期和时间的值“YYYY-MM-DD HH:MM:SS” 或YYYYMMDDHHMMSS,具体格式取决于是否函数中使用 一个字符串或数字上下文。

当然,你必须弄清楚不同的上下文是什么。一个提示。 -的使用是一个“数字上下文”。

接下来会发生什么。 MySQL会看到CURRENT_TIMESTAMP并放入当前时间。但是如何?它看到-并确定它作为一个数字。然后它遇到last_start。那么,现在也必须转换成一个数字。你猜怎么着?你会得到时髦的行为。

+0

'会代表后者使用前者的精彩(而且很奇怪) – 2014-09-19 05:12:44