Mar*_* An 6 mysql timestamp default-value mysql-5.7
在 mysql 5.7.28 中我创建了一个像这样的表:
create table t1 (
id int not null,
d1 timestamp)
engine=innodb;
Run Code Online (Sandbox Code Playgroud)
它工作正常并创建d1为, 。non-nulldefault value current_timetampon update current_timestamp
但是当我尝试创建具有两个时间戳字段的相同表时,如下所示:
create table t1 (
id int not null,
d1 timestamp,
d2 timestamp)
engine=innodb;
Run Code Online (Sandbox Code Playgroud)
我收到错误:
SQL 错误 (1067):“d2”的默认值无效
为什么只有在添加第二个时间戳字段时才会出现错误?
这是 mysql 中的错误还是某些预期行为?
小智 5
此行为在explicit_defaults_for_timestamp系统变量中进行了描述,默认情况下禁用, 5.6(5.7并且有效禁用5.1)并且启用中8.0。
引用上面的链接:
\n\n\n\n\n(5.7) 如果explicit_defaults_for_timestamp被禁用,服务器将启用非标准行为并按如下方式处理 TIMESTAMP 列:
\n\n\n
\n\n- 未使用 NULL 属性显式声明的 TIMESTAMP 列会自动使用 NOT NULL 属性进行声明。允许为此类列分配 NULL 值,并将该列设置为当前时间戳。
\n- 表中的第一个 TIMESTAMP 列,如果未使用 NULL 属性或显式 DEFAULT 或 ON UPDATE
\n
\n 属性显式声明,则自动使用 DEFAULT
\n CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 属性进行声明。- 第一个列之后的 TIMESTAMP 列,如果未使用 NULL 属性或显式 DEFAULT 属性显式声明,\n 将自动声明为 DEFAULT \'0000-00-00 00:00:00\'(\n \xe2\x80 \x9czero\xe2\x80\x9d 时间戳)。对于未为此类列指定显式值的插入行,该列将被分配“0000-00-00 00:00:00”并且不会出现警告。
\n根据是否启用严格 SQL 模式或 NO_ZERO_DATE SQL 模式,默认值“0000-00-00 00:00:00”可能无效。
\n
现在的问题5.7是该NO_ZERO_DATE模式已启用。这不允许将文档中描述的默认值0000-00-00 00:00:00添加为第一个后面的时间戳列中的默认值(如果未明确声明) 。
Mysql8.0仍然NO_ZERO_DATE启用该模式,但explicit_defaults_for_timestamp默认情况下启用环境变量,根据文档,它将添加 null 作为默认值,如下所示(这不会导致表创建时出现任何错误):
\n\n\n(8.0) 如果启用explicit_defaults_for_timestamp ,服务器将禁用\n非标准行为并按如下方式处理TIMESTAMP列:
\n\n[..]
\n\n\n
\n\n- 未使用 NOT NULL 属性显式声明的 TIMESTAMP 列将自动使用 NULL 属性进行声明,并允许使用 NULL 值。为此类列分配 NULL 值会将其设置为 NULL,而不是当前时间戳。
\n[..]
\n\n\n
\n- 表中第一个 TIMESTAMP 列的处理方式与第一个 TIMESTAMP 列之后的 TIMESTAMP 列的处理方式没有区别。
\n
此行为也在MySQL 的问题跟踪器上进行了讨论,但已标记为“不是错误”。
\n\n正如@Akina 在评论中提到的,不要依赖默认值。始终写下该字段的完整规范。
\n