MySQL未按预期执行CURRENT_TIMESTAMP更新

时间:2018-07-10 09:19:09

标签: mysql

经过大量研究并向here提出了一些类似的问题,我得出了一些结论,但与往常一样,还有更多问题。

这与explicit_defaults_for_timestamp

有关

假设 explicit_defaults_for_timestamp 已关闭,这将起作用:

模式:

CREATE TABLE IF NOT EXISTS `updated_tables` (
  `table_name` VARCHAR(50) NOT NULL,
  `updated_at` TIMESTAMP(6)  NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`table_name`),
  UNIQUE INDEX `table_name_UNIQUE` (`table_name` ASC))
  ENGINE = InnoDB;

查询:

INSERT INTO `updated_tables` (`table_name`,`updated_at`) VALUES ('products',NULL) ON DUPLICATE KEY UPDATE `table_name`=VALUES(`table_name`), `updated_at`=VALUES(`updated_at`);

首次发送查询时,该表中会填充“产品”和当前时间戳。 如果我重复查询,则字段“ updated_at”将更新。根据定义,当我发送NULL值时,即使不允许,MySQL也会更新该列。 一切都很好,并且可以按预期工作。

假设我打开了 explicit_defaults_for_timestamp 如果我使用上述查询,则会抱怨不允许使用NULL,这符合规则。

问题是,打开 explicit_defaults_for_timestamp 时,我如何具有相同的功能? 有一种解决方案,可以引入额外的列(varchar),该列​​可以保存例如以毫秒为单位的时间戳。当我更新它时,MySQL会相应地更新updated_at。 但这看起来有些矫kill过正,我不妨手动更新updated_at。我想将这种责任提升到MySQL级别,而不是通过编程来实现。

简而言之,我如何在table_name上执行更新,并正确设置Updated_at。这里的技巧是我有很多更新(缓存表),但实际上根本没有更改table_name的值。

有可能吗?还是我必须关闭explicit_defaults_for_timestamp?

将其关闭是否是错误的决定?看这篇AWS RDS帖子似乎还可以,但我不确定。

侧面问题:

如果我决定自己执行更新,那么构造它的方式将是什么? 当前,MySQL CURRENT_TIMESTAMP(6)具有以下构造: 2018-07-10 11:32:43.490100 如何使用JavaScript创建相同的构造?我首先想到的是获取当前日期,并将其附加到当前时间戳的后6位。

1 个答案:

答案 0 :(得分:1)

您可以在INSERT上创建触发器,并始终使用CURRENT_TIMESTAMP设置updated_at的值-这是最干净的方法,但这可能会减慢更新速度。以编程方式设置列值要比触发触发器快。

如果您要从Node.js执行查询,则可以使用new Date().getTime()以毫秒为单位获取Unix时间戳,然后像这样构建查询

UPDATE tbl SET col_1 = val_1, col_2 = val_2, updated_at = FROM_UNIXTIME(js_milliseconds / 1000) 
WHERE id = desired_id