MySQL 5.7中explicit_defaults_for_timestamp参数

在MySQL 5.7版本之前,且在MySQL 5.6.6版本之后(explicit_defaults_for_timestamp参数在MySQL 5.6.6开始加入)的版本中,如果没有设置explicit_defaults_for_timestamp=1的情况下:

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。

在MySQL 5.6.6及以后的版本和MySQL 5.7之前的版本中,如果在配置文件中没有指定explicit_defaults_for_timestamp参数,启动时error日志中会报如下警告:

[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=1,MySQL会按照如下的方式处理TIMESTAMP列:

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被指定了,那么会直接报错。如果strict sql_mode没有被指定,那么会向该列中插入’0000-00-00 00:00:00’并且产生一个warning。

这里为什么一直强调版本呢?主要还是因为这个参数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 5.7默认SQL模式带来的问题总结

一、启动mysql时未设置explicit_defaults_for_timestamp=1

1)创建测试表test_time

mysql> set session sql_mode='';

Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> create table test_time(time1 timestamp,time2 timestamp,id int);

Query OK, 0 rows affected (0.01 sec)

这里关闭了SQL模式,是因为MySQL 5.7默认SQL模式加入了NO_ZERO_DATE和NO_ZERO_IN_DATE模式,这两个模式的意思如下:

NO_ZERO_DATE

在严格模式,不要将’0000-00-00’做为合法日期。你仍然可以用IGNORE选项插入零日期。在非严格模式,可以接受该日期,但会生成警告。

NO_ZERO_IN_DATE

在严格模式,不接受月或日部分为0的日期(也就是说比NO_ZERO_DATE),对年不限制。如果使用IGNORE选项,我们为类似的日期插入’0000-00-00’。在非严格模式,可以接受该日期,但会生成警告。

所以如果不去掉这两个SQL模式,那么根据我们上面所说的表中的第一个TIMESTAMP列,如果没有指定null属性或者没有指定默认值,也没有指定ON UPDATE语句。那么该列会自动被加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性。第一个TIMESTAMP列之后的其他的TIMESTAMP类型的列,如果没有指定null属性,也没有指定默认值,那么该列会被自动加上DEFAULT ‘0000-00-00 00:00:00’属性。所以第二个timestamp添加默认值时就会报错的,错误如下:

mysql> create table test_time1(time1 timestamp,time2 timestamp,id int);

ERROR 1067 (42000): Invalid default value for 'time2'

表创建好了之后,下面来查看表结构信息,如下:

mysql> show create table test_time\G

*************************** 1. row ***************************

       Table: test_time

Create Table: CREATE TABLE `test_time` (

  `time1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

  `time2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

  `id` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

1 row in set (0.00 sec)

从表结构中可以看到表中timestamp列被自动设置为not null,并且表中第一个timestamp列被设置了DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP默认值,第二个字段默认值为”0000-00-00 00:00:00″。

2)插入测试

mysql> insert into test_time select null,null,1;

Query OK, 1 row affected (0.00 sec)

Records: 1  Duplicates: 0  Warnings: 0


mysql> select * from test_time;

+---------------------+---------------------+------+

| time1               | time2               | id   |

+---------------------+---------------------+------+

| 2017-02-22 15:42:11 | 2017-02-22 15:42:11 |    1 |

+---------------------+---------------------+------+

1 row in set (0.00 sec)

往timestamp列插入null值时,会自动为该列设置为current time。

插入时未指定值的timestamp列中被插入了0000-00-00 00:00:00(非表中第一个timestamp列)。

mysql> select * from test_time;

+---------------------+---------------------+------+

| time1               | time2               | id   |

+---------------------+---------------------+------+

| 2017-02-22 15:42:11 | 2017-02-22 15:42:11 |    1 |

| 2017-02-22 15:45:09 | 0000-00-00 00:00:00 |    1 |

+---------------------+---------------------+------+

2 rows in set (0.00 sec)

二、启动mysql时设置explicit_defaults_for_timestamp=1

1)创建表(不需要改变sql mode)

mysql> create table test_time(time1 timestamp,time2 timestamp,id int);

Query OK, 0 rows affected (0.00 sec)


mysql> show create table test_time\G

*************************** 1. row ***************************

       Table: test_time

Create Table: CREATE TABLE `test_time1` (

  `time1` timestamp NULL DEFAULT NULL,

  `time2` timestamp NULL DEFAULT NULL,

  `id` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

1 row in set (0.00 sec)

通过表结构我们看到,2个timestamp列都被设置为null,并且设置了默认值为null。

2)插入测试

mysql> insert into test_time select null,1;

Query OK, 1 row affected (0.00 sec)

Records: 1  Duplicates: 0  Warnings: 0


mysql> select * from test_time;

+-------+-------+------+

| time1 | time2 | id   |

+-------+-------+------+

| NULL  | NULL  |    1 |

+-------+-------+------+

1 row in set (0.00 sec)

为timestamp列指定了not null属性,在strict SQL mode时,如果插入时该列没有指定值,会直接报错。

mysql> create table test_time(time1 timestamp,time2 timestamp not null,id int);

Query OK, 0 rows affected (0.01 sec)


mysql> insert into test_time select null,null,1;

ERROR 1048 (23000): Column 'time2' cannot be null

如果为timestamp列指定not null属性,在非stric sql_mode模式下,如果插入的时候该列没有指定值,那么会向该列中插入0000-00-00 00:00:00,并且产生告警。

mysql> set session sql_mode='';

Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> insert into test_time select null,null,1;

Query OK, 1 row affected, 1 warning (0.00 sec)

Records: 1  Duplicates: 0  Warnings: 1


mysql> show warnings;

+---------+------+-------------------------------+

| Level   | Code | Message                       |

+---------+------+-------------------------------+

| Warning | 1048 | Column 'time2' cannot be null |

+---------+------+-------------------------------+

1 row in set (0.00 sec)


mysql> select * from test_time;

+-------+---------------------+------+

| time1 | time2               | id   |

+-------+---------------------+------+

| NULL  | 0000-00-00 00:00:00 |    1 |

+-------+---------------------+------+

1 row in set (0.00 sec)

上面说的都是关于timestamp类型的,如果是datetime呢?

mysql> create table time1(id int,time1 datetime,time2 datetime);

Query OK, 0 rows affected (0.03 sec)


mysql> show create table time1\G

*************************** 1. row ***************************

       Table: time1

Create Table: CREATE TABLE `time1` (

  `id` int(11) DEFAULT NULL,

  `time1` datetime DEFAULT NULL,

  `time2` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)


mysql> insert into time1(id) values(1);

Query OK, 1 row affected (0.00 sec)


mysql> select * from time1;

+------+-------+-------+

| id   | time1 | time2 |

+------+-------+-------+

|    1 | NULL  | NULL  |

+------+-------+-------+

1 row in set (0.00 sec)

可以看到跟普通类型一样。


转自:http://www.ywnds.com/?p=8309

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 什么是数据库? 数据库是存储数据的集合的单独的应用程序。每个数据库具有一个或多个不同的API,用于创建,访问,管理...
    chen_000阅读 4,033评论 0 19
  • 【MySQL】Linux下MySQL 5.5、5.6和5.7的RPM、二进制和源码安装 1.1BLOG文档结构图 ...
    小麦苗DB宝阅读 10,523评论 0 31
  • MySQL5.6从零开始学 第一章 初始mysql 1.1数据库基础 数据库是由一批数据构成的有序的集合,这些数据...
    星期四晚八点阅读 1,137评论 0 4
  • 用了mysql好多年,很少关注mysql自带库,自然也不知道这个库里存放些什么,在看《MySQL排错指南》时看到它...
    灼灼2015阅读 1,866评论 1 3
  • 充满了负能量 对大学的轻视,导致期中考的惨败,导致这段时间的低迷 但是啊,这样负能量能带来什么呢?还不是内心的堵,...
    米兰Milan阅读 91评论 0 1