如何从现有列中删除ON UPDATE CURRENT_TIMESTAMP?

时间:2015-08-05 17:55:13

标签: mysql timestamp

我做了一个mysql 5.5数据库的转储并将其加载到5.6服务器中。

转储将UPDATE CURRENT_TIMESTAMP添加到之前没有它的一堆列中。

我正在搜索ALTER TABLE语句,该语句将删除ON UPDATE CURRENT_TIMESTAMP规则而不进行任何其他更改。在我的想象中,它应该是ON UPDATE NOOPON UPDATE NO_CURRENT_TIMESTAMP

ON UPDATE JUST_BE_A_NORMAL_COLUMN

我尝试使用mysql workbench中的“Clear default”选项,它与它本应完成的操作相反 - 它为列提供了默认值!

我能够摆脱ALTER TABLE t ALTER COLUMN c DROP DEFAULT的默认值,因此INSERT中的列是必需的(就像我想要的那样在转储/重载之前),但UPDATE上的不需要的行为仍然存在。

我没有启用explicit_defaults_for_timestamp选项。如果我刚开始新鲜,我肯定会使用这个选项,因为它看起来更加清醒。但是因为我已经在5.5中按照我想要的方式配置了列,所以我希望它们在转移到5.6时保持相同的语义。显然mysqldump还不够聪明。

此时我不确定我是否理解启用explicit_defaults_for_timestamp会产生什么影响。该选项是否会更改现有表的行为,还是仅更改对未来CREATE TABLE命令的解释?将它打开以某种方式帮助我修复破碎的列?

更新

类似的问题是here但问题是关于创建新表而不是改变现有列。实际上,这个问题是我在5.5服务器上创建表时用作指南的问题。我使用了两步过程:使用默认值0创建以禁止ON UPDATE CURRENT_TIMESTAMP,然后删除默认值。

如果没有explicit_defaults_for_timestamp,那么两步程序肯定不会在5.6服务器上产生正确的结果;这是一个标志,5.6无法完美地模仿这种模式下的旧行为,或旧服务器从未做过我认为它正在做的事情。我无法确定是哪一个。

5 个答案:

答案 0 :(得分:17)

使用其他答案中的想法以及一些新安装的mysql服务器实例,我已经在3种不同的服务器配置上对几种不同的CREATE和ALTER命令的行为进行了比较:

  • mysql 5.5.45
  • mysql 5.6.26 without explicit_defaults_for_timestamp
  • mysql 5.6.26 with explicit_defaults_for_timestamp

最简单的解释是使用explicit_defaults_for_timestamp的5.6。一切都很清醒。时间戳类型与任何其他类型没有明显不同。在explicit_defaults_for_timestamp标志打开之前创建的列保留其旧的默认值和魔术更新。

在5.5中,隐式默认值在创建时间戳列时发生(如果它是表中的第一个时间戳列)。这些已经很好地记录在案。通过设置显式默认值可以避免魔术更新行为,然后可以删除默认值,使列具有3个所需属性:不可为空,无默认,无魔术更新。这是CREATE TABLE t (TIMESTAMP c NOT NULL DEFAULT 0)ALTER TABLE t ALTER COLUMN c DROP DEFAULT的结果。

使用单个CREATE TABLE命令无法重新创建此状态,并且它不能在mysqldump中存活。

没有explicit_defaults_for_timestamp的

5.6是最有趣的案例。它与5.5几乎相同,但DROP DEFAULT命令不同。如果您尝试“使用默认值创建0然后删除默认值”序列,则魔术更新属性将显示为放置的副作用。但是如果你使用默认的CURRENT_TIMESTAMP而不是0,那么DROP DEFAULT可以在没有副作用的情况下工作。 (必须是一个错误。我无法想象它会故意以这种方式行事。)

因此,这对命令在我测试的所有服务器配置上都会有相同的结果:

ALTER TABLE t CHANGE COLUMN c c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t ALTER COLUMN c DROP DEFAULT;

该列现在没有默认值,也没有魔术更新。

答案 1 :(得分:13)

ALTER TABLE mytable
     CHANGE mycolumn
            mycolumn TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

相信这会重置并使ON UPDATE无效。这将有效地做出这个定义:

CREATE TABLE mytable (
  # Other Columns
  mycolumn timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
)

换成这个:

CREATE TABLE mytable (
  # Other Columns
  mycolumn timestamp NOT NULL default CURRENT_TIMESTAMP
)

如果您想完全重置列,您应该可以简单地重新定义它:

ALTER TABLE mytable
     CHANGE mycolumn
            mycolumn TIMESTAMP NOT NULL;

答案 2 :(得分:0)

尝试启用explicit_defaults_for_timestamp系统变量,然后使用以下内容重新定义列:

ALTER TABLE `table` CHANGE COLUMN `col` `col` TIMESTAMP NOT NULL;

如果我理解documentation正确启用explicit_defaults_for_timestamp,则必须能够定义TIMESTAMP列,声明为NOT NULL且没有明确的DEFAULT。< / p>

答案 3 :(得分:0)

对于您的用例,我认为您可以更好地使用DATETIME,例如:

ALTER TABLE `my_table`
    CHANGE `my_col` `my_col` DATETIME NOT NULL DEFAULT NOW();

这将在插入时默认为NOW(),但在更新时不受影响。

有关差异的详细解释,请参阅此问题: Should I use field 'datetime' or 'timestamp'?

答案 4 :(得分:0)

如果您想同时删除DEFAULT值和ON UPDATE值,则以下内容对我没有帮助

ALTER TABLE `your_table` CHANGE `your_column` `your_column` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00';