MySQL自動更新列時間戳ON UPDATE CURRENT_TIMESTAMP

ON UPDATE很多人都用過,但什麼時候不觸發更新、更新有什麼壞處等細節,卻不一定都清楚。
讀完本文,您將掌握ON UPDATE的用法、新版本特性、使用陷阱和優缺點。

自動更新效果:當數據行發生更新時,數據庫自動設置“自動更新列”的值爲當前時間1

支持的字段類型

MySQL 5.6.5開始,TIMESTAMPDATETIME列都支持自動更新,且一個表可設置多個自動更新列。

MySQL 5.6.5之前,只有TIMESTAMP支持自動更新,且每個表只能有一個自動更新的時間列,而且不允許存在兩個列:其中一個設置了DEFAULT CURRENT_TIMESTAMP、另一個設置了ON UPDATE CURRENT_TIMESTAMP

下面主要介紹MySQL 5.6.5及之後版本的自動更新列用法。

語法

col DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
col TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

注意

自動更新的觸發時機

注意時間戳列“自動更新”的時機:

  • 插入時如未指定該列值時。
  • 當該行數據其他列有值變化時,如update
    • 如果有更新操作、但其他列值並未變化,不會觸發。此時要更新時間戳,需在SQL中指定新值給它(例如CURRENT_TIMESTAMP

      update table set column_tmt = CURRENT_TIMESTAMP

    • 如果更新時不想觸發,可顯式設置時間戳列爲當前值。

      update table set column_a = 'xxx', column_tmt = column_tmt

自動更新的時間值

CURRENT_TIMESTAMP還可以替換爲任何等價標識符,如CURRENT_TIMESTAMP()NOW()LOCALTIME等(所有獲取當前時間的標識符,可參考《MySQL日期與時間函數(日期/時間格式化、增減、對比、時區、UTC和UNIX時間)》

自動更新值時,CURRENT_TIMESTAMP表示的是SQL執行時的時間。如果要寫入實際每行數據發生變更的時間,需要執行SQL時手工設置自動更新列值爲SYSDATE(),自動更新列的聲明中、CURRENT_TIMESTAMP()不能替換爲SYSDATE()

DEFAULT設置

DEFAULT CURRENT_TIMESTAMP爲該列設置默認值。

DEFAULT後的CURRENT_TIMESTAMP可替換爲常量值,如2019-11-20 22:21:00

如果未設置DEFAULT,自動更新仍然生效,只是沒有默認值而已。TIMESTAMP的默認值爲0、除非聲明爲NULL纔會默認NULL,而DATETIME默認爲NULL、設置爲NOT NULL時默認值爲0.

系統變量explicit_defaults_for_timestamp會影響默認值情況。

爲了避免一些不必要的疏忽,建議自動更新列設置DEFAULT CURRENT_TIMESTAMP

精度

TIMESTAMP/DATETIME類型、及TIMESTAMP()函數一樣,支持最多6位小數位。

設置小數位時,各部分的精度必需保持一致,如:

col DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)

如果精度不一致、或部分設置了精度部分未設置,會報錯ERROR 1067 (42000): Invalid default value for 'tmt'

總結

自動更新列有好處也有不足:
好處:無需依賴業務實現時間戳,所有的db操作都會自動記錄,便於排查問題。
不足:數據庫服務器和業務服務器可能存在時間差,導致業務變動的時間與數據庫時間戳存在差異,給實際維護和使用帶來障礙。只能儘可能的校準服務器時間,但不能絕對避免該問題。

儘管如此,數據庫設計時仍建議增加一個自動更新列作爲時間戳,忠實反映數據庫的最後變化時間。


  1. https://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章