mysql explicit_defaults_for_timestamp参数

本文详细解析了MySQL中TIMESTAMP类型的默认值行为变化,包括在不同版本和配置下,TIMESTAMP列如何处理NULL值及默认值。特别是针对MySQL 5.6.6版本及其之后的变化进行了说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在mysql中:
- timestamp列如果没有显式定义为null,默认会被设置为not null属性。(其它的数据类型如果没有显式定义为not null,默认是可以为null的)。设置timestamp的列值为null,会自动存储为当前timestamp
- 表中的第一个timestamp列,如果没有定义为null、定义default值或者on update,会自动分配default current_timestamp和on update current_timestamp属性
- 表中第一个timestamp列之后的所有timestamp列,如果没有被定义为null、定义default值,会自动被指定默认值'0000-00-00 00:00:00'。在插入时,如果没有指定这些列的值,会自动指定为'0000-00-00 00:00:00',且不会产生警告

 1 mysql> create table timestamp_eg(
 2     ->     id int not null auto_increment,
 3     ->     time1 timestamp,
 4     ->     time2 timestamp,
 5     ->     time3 timestamp NOT NULL DEFAULT '2010-01-01 00:00:00',
 6     ->     time4 timestamp,
 7     ->     primary key(id));
 8 Query OK, 0 rows affected (0.01 sec)
 9  
10 mysql> insert into timestamp_eg(id) values(1);
11 Query OK, 1 row affected (0.00 sec)
12  
13 mysql> select * from timestamp_eg;
14 +----+---------------------+---------------------+---------------------+---------------------+
15 | id | time1               | time2               | time3               | time4               |
16 +----+---------------------+---------------------+---------------------+---------------------+
17 |  1 | 2015-12-16 09:23:33 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 0000-00-00 00:00:00 |
18 +----+---------------------+---------------------+---------------------+---------------------+
19 1 row in set (0.01 sec)
20  
21 mysql> update timestamp_eg set id=2 where id=1;
22 Query OK, 1 row affected (0.02 sec)
23 Rows matched: 1  Changed: 1  Warnings: 0
24  
25 mysql> select * from timestamp_eg;
26 +----+---------------------+---------------------+---------------------+---------------------+
27 | id | time1               | time2               | time3               | time4               |
28 +----+---------------------+---------------------+---------------------+---------------------+
29 |  2 | 2015-12-16 09:25:01 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 0000-00-00 00:00:00 |
30 +----+---------------------+---------------------+---------------------+---------------------+
31 1 row in set (0.00 sec)
32  
33 mysql> insert into timestamp_eg(id,time4) values(3,'2011-01-01 00:00:00');
34 Query OK, 1 row affected (0.00 sec)
35  
36 mysql> select * from timestamp_eg;
37 +----+---------------------+---------------------+---------------------+---------------------+
38 | id | time1               | time2               | time3               | time4               |
39 +----+---------------------+---------------------+---------------------+---------------------+
40 |  2 | 2015-12-16 09:25:01 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 0000-00-00 00:00:00 |
41 |  3 | 2015-12-16 09:28:04 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 2011-01-01 00:00:00 |
42 +----+---------------------+---------------------+---------------------+---------------------+
43 2 rows in set (0.00 sec)
44  
45 mysql> update timestamp_eg set id=4 where id=3;
46 Query OK, 1 row affected (0.00 sec)
47 Rows matched: 1  Changed: 1  Warnings: 0
48  
49 mysql> select * from timestamp_eg;
50 +----+---------------------+---------------------+---------------------+---------------------+
51 | id | time1               | time2               | time3               | time4               |
52 +----+---------------------+---------------------+---------------------+---------------------+
53 |  2 | 2015-12-16 09:25:01 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 0000-00-00 00:00:00 |
54 |  4 | 2015-12-16 09:28:24 | 0000-00-00 00:00:00 | 2010-01-01 00:00:00 | 2011-01-01 00:00:00 |
55 +----+---------------------+---------------------+---------------------+---------------------+
56 2 rows in set (0.00 sec)
57  
58 mysql>

从MySQL5.6.6这种默认设置的方法被废弃了。在MySQL启动时会出现以下警告:

1 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
2 Please use --explicit_defaults_for_timestamp server option (see
3 documentation for more details).

要想取消该警告,在启动mysql时,my.cnf中加入

1 [mysqld]
2 explicit_defaults_for_timestamp=true

修改该参数后,timestamp类型的列的处理方式也会发生变化:

- timestamp列如果没有显式定义为not null,则支持null属性。设置timestamp的列值为null,就不会被设置为current timestamp
- 不会自动分配default current_timestamp和on update current_timestamp属性,这些属性必须显式指定
- 声明为not null且没有显式指定默认值是没有默认值的。表中插入列,又没有给timestamp列赋值时,如果是严格sql模式,会抛出一个错误;如果严格sql模式没有启用,该列会赋值为’0000-00-00 00:00:00′,同时出现一个警告。(这和mysql处理其它时间类型数据一样,如datetime)

 1 mysql> create table timestamp_02(
 2     -> id int not null auto_increment,
 3     -> time1 timestamp not null,
 4     -> primary key(id)
 5     -> );
 6 Query OK, 0 rows affected (0.03 sec)
 7  
 8 mysql> insert into timestamp_02(id) values(1);
 9 ERROR 1364 (HY000): Field 'time1' doesn't have a default value
10 mysql>

作者:zqifa

出处:https://www.l1mn.com

### 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
发出的红包

打赏作者

z_qifa

此处弱弱求打赏~~万一有好心人

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值