[MySQL] Explicit_defaults_for_timestamp parameter analysis

When this parameter is set to OFF by default, its behavior is as follows:

  • By default, if the timestamp column does not explicitly specify the null attribute, then the column will be automatically added with the not null attribute (and if other types of columns are not explicitly specified not null, then null values ​​are allowed) , If you insert a null value into this column, it will automatically set the value of this column to the current timestamp value.

  • For the first timestamp column in the table, if the null attribute is not specified or the default value is not specified, and the ON UPDATE statement is not specified. Then the column will be automatically added DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes.

  • For other TIMESTAMP columns, if the specified NULL and DEFAULT attributes are not displayed, it will be automatically set to NOT NULL DEFAULT '0000-00-00 00:00:00'. (Of course, this is related to SQL_MODE. If SQL_MODE contains'NO_ZERO_DATE', it is actually not allowed to set its default value to '0000-00-00 00:00:00'.)

mysql> show variables like 'explicit_defaults_for_timestamp';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | OFF   |
+---------------------------------+-------+
 
mysql> create table t1 
    -> (
    -> ts1 timestamp,
    -> ts2 timestamp,
    -> ts3 timestamp default '2010-01-01 00:00:00'
    -> );
Query OK, 0 rows affected (0.03 sec)
 
mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `ts1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `ts2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ts3` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
 
mysql> insert into t1 values (null,null,null);
Query OK, 1 row affected (0.00 sec)
 
mysql> select * from t1;
+---------------------+---------------------+---------------------+
| ts1 | ts2 | ts3 |
+---------------------+---------------------+---------------------+
| 2019-04-09 15:54:56 | 2019-04-09 15:54:56 | 2019-04-09 15:54:56 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

From the perspective of the table structure, MySQL automatically sets the NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP attribute for the first timestamp field, and the following timestamp field, if not specified, is set **NOT NULL DEFAULT '0000-00-00 00 :00:00'** property. If you insert a null value into the timestamp column, the system will automatically set the value of the column to the current timestamp value. That is, when explicit_defaults_for_timestamp=OFF, a NULL value can be inserted even if the timestamp column is set to NOT NULL, and the system will automatically set the NULL value to current timestamp.

When this parameter is set to ON, its behavior is as follows:

  • If the timestamp column does not explicitly specify the not null attribute, then the default column can be null. At this time, when a null value is inserted into the column, null will be recorded directly instead of the current timestamp.

  • Will not automatically add DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes to the first timestamp column in the table.

  • If the timestamp column is added the not null attribute, and no default value is specified. At this time, if you insert a record into the table, but no value is specified for the TIMESTAMP column, if strict sql_mode is specified, an error will be reported directly. If strict sql_mode is not specified, then '0000-00-00 00:00:00' will be inserted into the column and a warning will be generated.

mysql> show variables like 'explicit_defaults_for_timestamp';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | ON    |
+---------------------------------+-------+
mysql> create table t2 
    -> (
    -> ts1 timestamp,
    -> ts2 timestamp,
    -> ts3 timestamp default '2010-01-01 00:00:00'
    -> );
Query OK, 0 rows affected (0.02 sec)
 
mysql> show create table t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `ts1` timestamp NULL DEFAULT NULL,
  `ts2` timestamp NULL DEFAULT NULL,
  `ts3` timestamp NULL DEFAULT '2010-01-01 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
 
mysql> insert into t2 values (null,null,null);
Query OK, 1 row affected (0.01 sec)
 
mysql> select * from t2;
+------+------+------+
| ts1 | ts2 | ts3 |
+------+------+------+
| NULL | NULL | NULL |
+------+------+------+
1 row in set (0.00 sec)
 
- Specify NOT NULL
mysql> create table t3 
    -> (
    -> ts1 timestamp,
    -> ts2 timestamp,
    -> ts3 timestamp not null
    -> );
Query OK, 0 rows affected (0.01 sec)
 
mysql> show create table t3\G
*************************** 1. row ***************************
       Table: t3
Create Table: CREATE TABLE `t3` (
  `ts1` timestamp NULL DEFAULT NULL,
  `ts2` timestamp NULL DEFAULT NULL,
  `ts3` timestamp NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
 
mysql> insert into t3 values (null,null,null);
ERROR 1048 (23000): Column 'ts3' cannot be null
 
mysql> insert into t3 (ts1,ts2) values (null,null);
Query OK, 1 row affected, 1 warning (0.01 sec)
 
mysql> show warnings;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1364 | Field 'ts3' doesn't have a default value |
+---------+------+------------------------------------------+
 
mysql> select * from t3;
+------+------+---------------------+
| ts1 | ts2 | ts3 |
+------+------+---------------------+
| NULL | NULL | 0000-00-00 00:00:00 |
+------+------+---------------------+

It can be seen from the table structure that when the parameter is turned on, MySQL will add a null default null attribute to the timestamp column by default, and MySQL has not set the column to the current timestamp value for the first timestamp field. The timestamp field writes a null value, and the null value is stored after writing, not the current time. When the timestamp field specifies NOT NULL, if you explicitly insert NULL, an error message will be reported: the field cannot be empty; if you do not explicitly insert the field and SQL_MODE does not contain'NO_ZERO_DATE', then '0000-00- 00 00:00:00' and generate a warning.

CREATE TABLE `table_name` (
  `increment_id` INT UNSIGNED NOT NULL auto_increment COMMENT '自增主键',
  ...
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'create time',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`increment_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

At this time, the timestamp field will specify NOT NULL. At this time, it is recommended that the explicit_defaults_for_timestamp parameter use the default OFF, so that no error will be reported when the timestamp field is explicitly inserted with a NULL value, especially when the program sql is not written properly, which can avoid program insertion error.

Guess you like

Origin blog.51cto.com/13598811/2591092