我做了一个mysql 5.5数据库的转储并将其加载到5.6服务器中。
转储将UPDATE CURRENT_TIMESTAMP添加到之前没有它的一堆列中。
我正在搜索ALTER TABLE
语句,该语句将删除ON UPDATE CURRENT_TIMESTAMP规则而不进行任何其他更改。在我的想象中,它应该是ON UPDATE NOOP
或ON 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无法完美地模仿这种模式下的旧行为,或旧服务器从未做过我认为它正在做的事情。我无法确定是哪一个。
答案 0 :(得分:17)
使用其他答案中的想法以及一些新安装的mysql服务器实例,我已经在3种不同的服务器配置上对几种不同的CREATE和ALTER命令的行为进行了比较:
最简单的解释是使用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';