[mysql] timestamp自動更新和初始化

1.概述html

在咱們設計表的時候,考慮將行數據的建立時間和最後更新時間記錄下來是很好的實踐。尤爲是可能須要作數據同步或者對數據新鮮度有要求的表。舉些應用場景,更新距上次更新超過2小時的行數據,或者是將一個月前的訂單數據歸檔等等。咱們想把這個的需求丟給數據庫服務器管理,而不是在應用程序中對每一條語句設置建立時間和最後更新時間字段。在mysql中,這實現起來很容易。咱們須要藉助於DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPmysql

2.簡單示例sql

 1 --建立測試表
 2 CREATE TABLE `timestampTest` (
 3   `id` int(11) NOT NULL AUTO_INCREMENT,
 4   `name` varchar(20) DEFAULT NULL,
 5   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 6   `last_modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 7   PRIMARY KEY (`id`)
 8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 9 
10 --檢測默認值,插入測試數據
11 INSERT INTO timestampTest (name) VALUES ('aa'),('bb'),('cc');
12 
13 --檢測自動更新,更新某條數據
14 UPDATE timestampTest SET name = 'ab' WHERE id = 1;

例子很是簡單,結果也很明顯,我就不加贅述了。數據庫

3.思考服務器

  • 執行update語句,並未改變列值(或者說設置值爲當前值),on update current_timestamp列是否會更新?測試

    不會,你們能夠看一下執行完update後出現的提示——Rows matched: 1 Changed: 0 Warnings: 0。官方文檔的解釋是spa

An auto-updated column remains unchanged if all other columns are set to their current values. To prevent an auto-updated column from updating when other columns change, explicitly set it to its current value. To update an auto-updated column even when other columns do not change, explicitly set it to the value it should have設計

    

  • CURRENT_TIMESTAMP,CURRENT_TIMESTAMP(),LOCALTIME,LOCALTIME(),LOCALTIMESTAMP,LOCALTIMESTAMP(),NOW()的關係?code

    這七個是同義詞關係htm

  • Timestamp類型的默認值

    咱們討論默認狀況(嚴格模式)下mysql對timestamp類型的處理:

    1. mysql不會給timestamp設置默認值,除非顯式設置default約束或者可空null。特例:mysql會給表第一個timestamp類型的字段同時添加default current_timestamp和on update timestamp
    2. 禁止mysql的特例處理有兩個辦法
      1. 設置explicit_defaults_for_timestamp爲enable
      2. 顯式設置該字段default或者null
    3. timestamp列默認not null。沒有顯式指定nullable,那麼default null不合法
    4. 其餘狀況均會引發不合法報錯

舉一些例子,幫助理解

 1 #語句不合法,出現了兩個未顯示設置default或null的timestamp
 2 CREATE TABLE `tt1` (
 3   `id` int(11) NOT NULL AUTO_INCREMENT,
 4   `name` varchar(20),
 5   `t1` timestamp ,
 6   `t2` timestamp ,
 7   PRIMARY KEY (`id`)
 8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 9 
10 #語句合法,t1字段 not null default current_timestamp on update current_timestamp,t2可空
11 CREATE TABLE `tt2` (
12   `id` int(11) NOT NULL AUTO_INCREMENT,
13   `name` varchar(20),
14   `t1` timestamp ,
15   `t2` timestamp null,
16   PRIMARY KEY (`id`)
17 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
18 
19 #語句不合法 t2字段沒有設置default或null,也非表的第一個timestamp字段
20 CREATE TABLE `tt3` (
21   `id` int(11) NOT NULL AUTO_INCREMENT,
22   `name` varchar(20),
23   `t1` timestamp null,
24   `t2` timestamp ,
25   PRIMARY KEY (`id`)
26 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
27 
28 #語句不合法,這個看起來貌似合法,套用咱們的規則,能夠發現t2字段沒有顯示指定null/default,儘管指定了not null也不行
29 CREATE TABLE `tt4` (
30   `id` int(11) NOT NULL AUTO_INCREMENT,
31   `name` varchar(20),
32   `t1` timestamp null,
33   `t2` timestamp not null,
34   PRIMARY KEY (`id`)
35 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
36 
37 #語句不合法 t1,t2均合法,問題出在t3上,timestamp 默認not null,在沒有顯式指定null的時候,default null是不合法的 38 CREATE TABLE `tt5` (
39   `id` int(11) NOT NULL AUTO_INCREMENT,
40   `name` varchar(20),
41   `t1` timestamp not null,
42   `t2` timestamp null,
43   `t3` timestamp DEFAULT null,
44   PRIMARY KEY (`id`)
45 ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  小技巧:能夠使用show create table `tablename` 來查看mysql處理後的表定義,下面是tt2這張表的定義,驗證了咱們的結論

  

  • Timestamp和datetime的異同
  timestamp datetime
可自動更新和初始化,默認顯示格式相同YYYY-MM-dd HH:mm:ss

'1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC

自動時區轉化,實際存儲毫秒數,4字節存儲

'1000-01-01 00:00:00' to '9999-12-31 23:59:59'

不支持時區,8字節存儲

4.參考

1.Automatic Initialization and Updating for TIMESTAMP and DATETIME

2.Date and Time Functions

相關文章
相關標籤/搜索