1. 程式人生 > >mysql explicit_defaults_for_timestamp 變數的作用

mysql explicit_defaults_for_timestamp 變數的作用

mysql 中有這樣的一個預設行為,如果一行資料中某些列被更新了,如果這一行中有timestamp型別的列,那麼麼這個timestamp列的資料

也會被自動更新到 更新操作所發生的那個時間點;這個操作是由explicit_defaults_for_timestamp這個變更控制的

 

一、體驗一下mysql的預設更新行為

mysql> create table t(x int ,y timestamp);  -- 建立一個帶有timestamp列的表
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t(x) values(1);  -- 只插x列
Query OK, 1 row affected (0.00 sec)

mysql> select * from t; -- timestamp列會自動更新
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    1 | 2017-06-07 13:48:56 |
+------+---------------------+
1 row in set (0.00 sec)

mysql> update t set x=2 where x=1; -- update 時timestamp列還是會自動更新
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    2 | 2017-06-07 13:49:21 |
+------+---------------------+
1 row in set (0.00 sec)
 

二、如何關閉這一預設行為

  聰明的你一想到了,只要把explicit_defaults_for_timestamp這個變更設定為on;對於timestamp列的值都要顯示指定,那麼這一預設行為就

  算是關閉了。來操作一把!

mysql> set @@global.explicit_defaults_for_timestamp=on; -- 把全域性的設定為on 那麼新的連線就會被設定成on
Query OK, 0 rows affected (0.00 sec)

mysql> set @@session.explicit_defaults_for_timestamp=on; -- 把當前連線explicit_defaults_for_timestamp設定為on
Query OK, 0 rows affected (0.00 sec)

mysql> update t set x=3 ; -- 第一次更新 結果是變了
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    3 | 2017-06-07 13:57:21 |
+------+---------------------+
row in set (0.00 sec)

mysql> update t set x=4 ; -- 第二次更新 結果還是變了
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    4 | 2017-06-07 13:57:52 |
+------+---------------------+
row in set (0.00 sec)

mysql> show variables like 'explicit_defaults_for_timestamp'; -- 全域性發動生效
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | ON    |
+---------------------------------+-------+
row in set (0.00 sec)

mysql> show global variables like 'explicit_defaults_for_timestamp'; -- session 級別改動也升效了
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | ON    |
+---------------------------------+-------+
row in set (0.00 sec)

-- 發現了吧、就算把explicit_defaults_for_timestamp 設定成了on 也不會有效的

三、找問題出在了哪裡

  1、explicit_defaults_for_timestamp=off 時表結構

CREATE TABLE `t` (
  `x` int(11) DEFAULT NULL,
  `y` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- `y` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE

  2、explicit_defaults_for_timestamp=on 時表結構

CREATE TABLE `t6` (
  `x` int(11) DEFAULT NULL,
  `y` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- `y` timestamp NULL DEFAULT NULL

 

四、結論

  explicit_defaults_for_timestamp 變數會直接影響表結構,也就是說explicit_defaults_for_timestamp的作用時間

  是在表定義的時候;你的update | insert 想通過它去改變行為已經太晚了!

 

五、如何解決這失控的場面

  1、改表結構

mysql> alter table t modify column y timestamp null default null; -- 解決辦法改表結構
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> update t set x=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    1 | 2017-06-07 13:59:21 |
+------+---------------------+
row in set (0.00 sec)

mysql> update t set x=2; -- 再次對比,發現時間沒有變哦!
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+------+---------------------+
| x    | y                   |
+------+---------------------+
|    2 | 2017-06-07 13:59:21 |
+------+---------------------+
row in set (0.00 sec)