MySQL的explicit_defaults_for_timestamp参数问题

 

先看官方的描述:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html

 

这个参数全局或者sessioin都可以设置,默认是不开启的,可以这样理解:如果一行数据中某些列被更新了,如果这一行中有timestamp类型的列,那么么这个timestamp列的数据也会被自动更新到 更新操作所发生的那个时间点;这个操作是由explicit_defaults_for_timestamp这个变更控制的,大概有有以下几种情况:

1、当explicit_defaults_for_timestamp为OFF不打开的时候:

   a)如果TIMESTAMP列没有显示的指明null属性,那么该列会被自动加上not null属性,如果往这个列中插入null值,会自动的设置该列的值为current timestamp值。

   b)表中的第一个TIMESTAMP列,如果没有指定null属性或者没有指定默认值,也没有指定ON UPDATE属性。那么该列会自动被加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性。

   c)如果表中有多个TIMESTAMP列,第一个TIMESTAMP列之后的其他的TIMESTAMP类型的列,如果没有指定null属性,也没有指定默认值,那么该列会被自动加上DEFAULT ‘0000-00-0000:00:00’属性。如果insert语句中没有为该列指定值,那么该列中插入’0000-00-00 00:00:00’,并且没有warning。
 

2、当explicit_defaults_for_timestamp为ON打开的时候:

   a)此时如果TIMESTAMP列没有显示的指定not null属性,那么默认的该列可以为null,此时向该列中插入null值时,会直接记录null,而不是current timestamp。

   b)不会自动的为表中的第一个TIMESTAMP列加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性,除非你在建表的时候显示的指明NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。但这时如果插入值为NULL就会直接报错。

   c)timestamp字段有not null属性,而且不允许为空值;在strict的sql模式下,如果你insert语句里面有默认值为null值会报错;使用'0000-00-00 00:00:00'的默认值,会自动用这个默认值。

   d)timestamp字段带有not null属性,而且没有默认值,inset式不指定该字段的值,strict sql_mode下,会报错。非strict sql_mode下有默认值'0000-00-00 00:00:00'的话会录入默认值,这有点想datetime字段。

 

3、版本的差异

这个参数explicit_defaults_for_timestamp在MySQL 5.6.6开始加入,并且MySQL 5.6跟MySQL 5.7的默认SQL模式不同,MySQL 5.7的SQL模式更加严格了,限制了不合法的日期输入,比如”0000-00-00 00:00:00″。

 

 

### MySQL `explicit_defaults_for_timestamp` 参数的作用 `explicit_defaults_for_timestamp` 是一个 MySQL 全局变量,用于控制服务器对 `TIMESTAMP` 列的行为方式。具体来说,它决定了 `TIMESTAMP` 列的默认值以及是否允许存储特殊值 `'0000-00-00 00:00:00'` 或者 `NULL` 值。 #### 当 `explicit_defaults_for_timestamp=OFF` 在这种情况下,MySQL 使用一种向后兼容的方式处理 `TIMESTAMP` 列: - 如果未显式定义 `DEFAULT` 和 `NULL` 属性,则 `TIMESTAMP` 列会被设置为 `NOT NULL DEFAULT '0000-00-00 00:00:00'`[^5]。 - 此外,在某些 SQL 模式下(如包含 `NO_ZERO_DATE`),这种行为可能会受到限制,从而阻止将非法日期作为默认值[^4]。 #### 当 `explicit_defaults_for_timestamp=ON` 启用此选项时,MySQL 不再使用上述隐式的默认行为,而是完全依赖用户的声明来定义 `TIMESTAMP` 列的特性: - 用户必须明确指定每一列是否支持 `NULL` 值及其默认值。 - Airflow 等工具通常需要这样的配置才能正常工作,因为它期望 `TIMESTAMP` 列具有更严格的语义,即默认值应为 `NULL` 而不是 `'0000-00-00 00:00:00'`[^2]。 --- ### 设置方法 可以通过修改 MySQL 配置文件或者通过命令行动态调整该参数的值。 #### 方法一:编辑 my.cnf 文件 找到并编辑 MySQL 的配置文件 (`my.cnf`) ,在 `[mysqld]` 下添加或更改如下内容: ```ini [mysqld] explicit_defaults_for_timestamp=ON ``` 保存文件后重启 MySQL 服务使改动生效。 #### 方法二:运行 SET GLOBAL 命令 也可以直接执行 SQL 查询以临时改变这一设定(仅限当前会话有效): ```sql SET GLOBAL explicit_defaults_for_timestamp = ON; ``` 注意这种方式不会持久化到下次启动之后;如果希望永久应用新设值,请采用第一种办法[^3]。 --- ### 示例代码展示 假设我们创建一张表 test_table 来观察不同状态下 timestamp 行为差异: ```sql CREATE TABLE test_table ( id INT PRIMARY KEY, created_at TIMESTAMP -- No attributes specified here. ); ``` 当 `explicit_defaults_for_timestamp=OFF` 时,created_at 将自动获得 NOT NULL 并且其初始值将是 ‘0000-00-00 00:00:00’ (除非受 sql_mode 影响)[^1]。 而一旦切换至 ON 状态,尝试插入记录而不提供 created_at 数据将会引发错误,直到开发者自行赋予合适的属性为止。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值