explicit_defaults_for_timestamp 参数说明
官方文档:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp
命令行格式 | --explicit-defaults-for-timestamp[={OFF|ON}] |
---|---|
已弃用 | 是的 |
系统变量 | explicit_defaults_for_timestamp |
范围 | 全局,会话 |
动态的 | 是的 |
类型 | 布尔值 |
默认值 | OFF |
说明 :
此系统变量确定服务器是否为列中的默认值和NULL
-value 处理 启用某些非标准行为 TIMESTAMP
。默认情况下, explicit_defaults_for_timestamp
禁用,这将启用非标准行为。
如果 explicit_defaults_for_timestamp
禁用,则服务器启用非标准行为并按TIMESTAMP
如下方式处理列:
-
TIMESTAMP
未使用NULL
属性显式声明的列会自动使用该NOT NULL
属性声明。NULL
允许为这样的列分配值,并将该列设置为当前时间戳。 -
TIMESTAMP
表中 的第一列如果没有用NULL
属性或显式DEFAULT
或ON UPDATE
属性显式声明 ,则自动用DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
属性声明 。 -
TIMESTAMP
第一个列之后的列,如果未使用NULL
属性或显式DEFAULT
属性显式声明 ,则自动声明为DEFAULT '0000-00-00 00:00:00'
(“零”时间戳)。对于没有为此类列指定显式值的插入行,将分配该列'0000-00-00 00:00:00'
并且不会发生警告。根据是否
NO_ZERO_DATE
启用了严格 SQL 模式或 SQL 模式,默认值'0000-00-00 00:00:00'
可能无效。请注意,TRADITIONAL
SQL 模式包括严格模式和NO_ZERO_DATE
. 请参阅 第 5.1.10 节,“服务器 SQL 模式”。
刚刚描述的非标准行为已被弃用;希望在未来的 MySQL 版本中删除它们。
如果 explicit_defaults_for_timestamp
启用,服务器将禁用非标准行为并按TIMESTAMP
如下方式处理列:
-
无法为
TIMESTAMP
列分配 值NULL
以将其设置为当前时间戳。要分配当前时间戳,请将列设置为CURRENT_TIMESTAMP
或 同义词,例如NOW()
。 -
TIMESTAMP
未使用NOT NULL
属性显式声明的列会自动使用NULL
属性和许可NULL
值进行声明。为这样的列分配一个值NULL
将其设置为NULL
,而不是当前时间戳。 -
TIMESTAMP
用NOT NULL
属性声明的列不允许NULL
值。对于NULL
为此类列指定的插入,结果要么是启用严格 SQL 模式的单行插入错误,要么'0000-00-00 00:00:00'
是禁用严格 SQL 模式的多行插入错误。在任何情况下都不会为列分配一个值,NULL
将其设置为当前时间戳。 -
TIMESTAMP
使用NOT NULL
属性显式声明而没有显式DEFAULT
属性的列被视为没有默认值。对于没有为此类列指定显式值的插入行,结果取决于 SQL 模式。如果启用了严格 SQL 模式,则会发生错误。如果未启用严格 SQL 模式,则使用隐式默认值声明该列'0000-00-00 00:00:00'
并出现警告。这类似于 MySQL 处理其他时间类型的方式,例如DATETIME
. -
没有
TIMESTAMP
使用DEFAULT CURRENT_TIMESTAMP
或ON UPDATE CURRENT_TIMESTAMP
属性自动声明列。必须明确指定这些属性。 -
TIMESTAMP
表中 第一列的处理方式TIMESTAMP
与第一列之后的列没有区别 。
如果 explicit_defaults_for_timestamp
在服务器启动时禁用,错误日志中会出现此警告:
[Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
Please use --explicit_defaults_for_timestamp server option (see
documentation for more details).
如警告所示,要禁用已弃用的非标准行为,请explicit_defaults_for_timestamp
在服务器启动时启用 系统变量。
解读:
explicit_defaults_for_timestamp 参数默认值为OFF,
当这个参数值为OFF时,建表语句中的timestamp类型字段会按照如下规则处理,
1、如果timestamp未使用null属性显式的声明字段类型,则会自动使用not null属性进行声明。
2、表中第一个timestamp字段列,如果没有使用 null 、default 或 on update 显式声明,则会自动使用 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 进行声明。
3、表中第一个tiemstamp字段之后的列,如果没有使用 null 、default 或 on update 显式声明,则会自动使用 default '0000-00-00 00:00:00' 进行声明。
注意:根据sql_mode参数是否启用了 NO_ZERO_DATE
,或者使用了严格模式 TRADITIONAL
,默认值 '0000-00-00 00:00:00' 可能无效。
例1(explicit_defaults_for_timestamp=OFF ,建表语句不显式指定null 、default 、 on update):
建表语句中,sj 字段并没有显式的设置是否为Null,一般情况下,创建不指定not null的情况时,都是允许为null,
但在MySQL中受 explicit_defaults_for_timestamp 参数影响,建表语句已经发生了变化。
所有的timestamp列都是not null defaul xxxx ,第一个timestamp列还自动加上了on update CURRENT_TIMESTAMP
mysql> show global variables like '%explicit_defaults_for_timestamp%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | OFF |
+---------------------------------+-------+
1 row in set (0.00 sec)
mysql> drop table tt; Query OK, 0 rows affected (0.00 sec) mysql> create table tt(id int primary key,sj timestamp,sj1 timestamp ,sj2 timestamp); Query OK, 0 rows affected (0.01 sec) mysql> show create table tt\G *************************** 1. row *************************** Table: tt Create Table: CREATE TABLE `tt` ( `id` int(11) NOT NULL, `sj` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `sj1` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `sj2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
例2(explicit_defaults_for_timestamp=OFF ,建表语句显式指定null 、default 、 on update):
第一个timestamp列显式指定了null 属性,没有受到参数影响。
第二个timestamp列显式指定了default属性,没有受到参数影响。
第三个timestamp列,只显式指定了on update CURRENT_TIMESTAMP,并没有显式指定null 或 default值,会受参数影响,自动加上not null default xxx
mysql> show global variables like '%explicit_defaults_for_timestamp%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | explicit_defaults_for_timestamp | OFF | +---------------------------------+-------+ 1 row in set (0.00 sec) mysql> drop table tt; Query OK, 0 rows affected (0.00 sec) mysql> create table tt(id int primary key,sj timestamp null ,sj1 timestamp default '2008-08-08 08:08:08',sj2 timestamp ON UPDATE CURRENT_TIMESTAMP); Query OK, 0 rows affected (0.01 sec) mysql> show create table tt\G *************************** 1. row *************************** Table: tt Create Table: CREATE TABLE `tt` ( `id` int(11) NOT NULL, `sj` timestamp NULL DEFAULT NULL, `sj1` timestamp NOT NULL DEFAULT '2008-08-08 08:08:08', `sj2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
例3(explicit_defaults_for_timestamp=ON):
服务器将禁用非标准行为,timestamp列按如下方式处理
无法为timestamp列null属性分配当前时间戳,要分配当前时间戳,请将列设置为current_timestamp或同义词,比如now()
timestamp未使用not null显式定义列属性,会自动使用null属性和默认null值进行定义。
timestamp使用not null进行定义,但如果插入null值时,受SQL_MODEC严格模式影响,要么会报错,要么会写入'0000-00-00 00:00:00'
表中第一个timestamp列与之后的tiemstamp列处理方式没有区别。
mysql> create table tt(id int primary key,sj timestamp,sj1 timestamp not null,sj2 timestamp ON UPDATE CURRENT_TIMESTAMP); Query OK, 0 rows affected (0.01 sec) mysql> show create table tt\G *************************** 1. row *************************** Table: tt Create Table: CREATE TABLE `tt` ( `id` int(11) NOT NULL, `sj` timestamp NULL DEFAULT NULL, `sj1` timestamp NOT NULL, `sj2` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> insert into tt select 1,null,null,null; Query OK, 1 row affected, 1 warning (0.00 sec) Records: 1 Duplicates: 0 Warnings: 1 mysql> select * from tt\G *************************** 1. row *************************** id: 1 sj: NULL sj1: 0000-00-00 00:00:00 sj2: NULL 1 row in set (0.00 sec)