Mysql系统参数explicit_defaults_for_timestamp

时间:2023-02-06 12:01:32

一、概述

explicit_defaults_for_timestamp 系统变量决定MySQL服务端对timestamp列中的默认值和NULL值的不同处理方法。
此变量自MySQL 5.6.6 版本引入,分为全局级别和会话级别,可动态更新,默认值为OFF。
用5.6.20版本做实验发现该参数已经不支持动态更新,read only variable,只能配置文件修改
本文主要介绍该参数打开和关闭情况下对timestamp的影响 。

show variables like 'explicit_defaults_for_timestamp'; ==>OFF

二、参数效果

1、OFF(默认值)

1、介绍
explicit_defaults_for_timestamp = OFF
当该参数默认设置为OFF时,其行为如下:
1)在默认情况下,如果TIMESTAMP列没有显示的指明null属性,那么该列会被自动加上not null属性(而其他类型的列如果没有被显示的指定not
null,那么是允许null值的),如果往这个列中插入null值,会自动的设置该列的值为current timestamp值。
2)表中的第一个TIMESTAMP列,如果没有指定null属性或者没有指定默认值,也没有指定ON UPDATE语句。那么该列会自动被加上DEFAULT
CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性。
3)第一个TIMESTAMP列之后的其他的TIMESTAMP类型的列,如果没有指定null属性,也没有指定默认值,那么该列会被自动加上DEFAULT
‘0000-00-00 00:00:00’属性。如果insert语句中没有为该列指定值,那么该列中插入’0000-00-00 00:00:00’,并且没有warning。
(当然,这个与SQL_MODE有关,如果SQL_MODE中包含’NO_ZERO_DATE’,实际上是不允许将其默认值设置为’0000-00-00 00:00:00’的。建表就会
失败报错大概为:"1067: Invalid default value for 'end_date'")

2、试验(sql_mode不包含NO_ZERO_DATE)
2.1创建表
create table test (
col1 timestamp,
col2 timestamp,
col3 timestamp default '2010-01-01 00:00:00'
);
2.2查看表
show create table test;
create table test (
col1 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
col2 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
col3 timestamp NOT NULL DEFAULT '2010-01-01 00:00:00'
)ENGINE=innodb charset=utf8;
2.3插入数据
insert into test values (null,null,null);
2.4查看数据
select * from test;
2022-02-04 14:32:26 2022-02-04 14:32:26 2022-02-04 14:32:26

3、总结
MySQL自动为第一个timestamp字段自动设置NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP属性;
而后面的timestamp字段,虽然设置了 **NOT NULL DEFAULT ‘0000-00-00 00:00:00’**属性,如果向timestamp这个列中插入null值,
系统会自动的设置该列的值为current timestamp值。

综上所述:
当explicit_defaults_for_timestamp=OFF时,即使timestamp列设为NOT NULL也能插入NULL值,系统会自动将NULL值设为current timestamp。

2、on

1、介绍
explicit_defaults_for_timestamp=1
1)此时如果TIMESTAMP列没有显示的指定not null属性,那么默认的该列可以为null,此时向该列中插入null值时,会直接记录null,而不是current timestamp。
2)不会自动的为表中的第一个TIMESTAMP列加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性,除非你在建表的时候显示
的指明。
3)如果TIMESTAMP列被加上了not null属性,并且没有指定默认值。这时如果向表中插入记录,但是没有给该TIMESTAMP列指定值的时候,如果strict
sql_mode被指定了,那么会直接报错。
4)如果strict sql_mode没有被指定,那么会向该列中插入’0000-00-00 00:00:00’并且产生一个warning。

2、试验
已经无法动态更新,只能通过配置文件更改重启
2.1、创建数据库
create table test (
col1 timestamp,
col2 timestamp,
col3 timestamp default '2010-01-01 00:00:00'
);
2.2、插入数据
insert into test values (null,null,null);
2.3、查询数据
select * from test;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| NULL | NULL | NULL |
+------+------+------+