timestamp的自動更新 ON UPDATE CURRENT_TIMESTAMP


最近有一個關於MySQL版本升級的事,涉及到一些關於時間類型的細節問題需要查明,因此到官網找到相關文章,翻出來比較方便自己理解,博客這里也貼一下。

參考官網網址:

https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html

自MySQL 5.6.5開始TIMESTAMP和DATETIME類型可以實現自動初始化或更新為CURRENT_TIMESTAMP的功能,在5.6.5之前這個特性只有TIMESTAMP才能用。鑒於現在時間類型基本都用DATETIME(因為TIMESTAMP的范圍很小局限性也很大),因此5.6.5之后DATETIME也實現了這個功能。
這個功能詳細描述下就是:
  • DATETIME也可以像TIMESTAMP一樣將CURRENT_TIMESTAMP設為默認值
  • 如果你為此時間列設置了自動更新的屬性,那么只要一條記錄的其他任何列值發生改變,時間列都會自動更新為CURRENT_TIMESTAMP。
假如你不想讓設置自動更新屬性的時間列隨其他列值的改變而改變,你可以為他顯式的賦一個值。
TIMESTAMP類型的表現:
  • 默認的,在8.0.2版本之前,如果你未顯式的將timestamp設置為NULL,那么timestamp列會被自動設置為not null,給這種字段顯式賦NULL值會自動存為current_timestamp 。
  • 默認的,在8.0.2版本之前,對於表中的第一個timestamp列,如果你未顯式的指定可以為NULL,且未指定默認值,且未指定on update屬性,那么這個列會被自動設置為:NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。
  • 默認的,在8.0.2版本之前,對於表中的非第一個timestamp列,如果你未顯式的指定可以為NULL,且未指定默認值,那么默認值會自動設置為'0000-00-00 00:00:00'。
以上現象官網稱之為:nonstandard behaviors
在5.6.6之前,這可以算是他相比datetime的一個優勢,也有人把它視為一個BUG認為他很麻煩,但無論如何在5.6.6之前如果你有將CURRENT_TIMESTAMP設為默認值的需求,那你只能選擇timestamp類型。不過好在5.6.6之后datetime也支持設置CURRENT_TIMESTAMP默認值啦。
為了避免上述timestamp的nonstandard behaviors, MySQL5.6.6引入了explicit_defaults_for_timestamp參數:
此參數在8.0.1之前的版本默認是OFF,只讀參數,而在MySQL8.0.2之后此參數默認值變為ON而且可以在線修改。
將explicit_defaults_for_timestamp設為ON之后,timestamp的表現如下:
  • 向timestamp插入NULL值不會自動存為current_timestamp啦,如果想要存current_timestamp,那么直接賦值為current_timestamp或者其同義詞,例如now().
  • timestamp列如果不顯式的指定為not null,那么默認就是NULL,想這個列插入NULL值存的就是NULL,而不是current_timestamp。
  • 指定not null的timestamp列不再允許插入NULL值,如果你強行為此列插入NULL值,那么要么返回一個錯誤,要么插入'0000-00-00 00:00:00'(與SQL mode有關)。
  • 對於設置了not null且未設置default值的timestamp列,向這種表插入數據時如果未指定timestamp列的值,那么插入結果取決於sql_mode,如果是strict SQL mode那么直接報錯,否則插入'0000-00-00 00:00:00'並報一個warning。
  • timestamp列不再會被自動設為DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,你必須手動設置。
  • 表中的首個timestamp列也不再和其他timestamp列有差別。

因此可以看到explicit_defaults_for_timestamp參數的作用其實就是讓你可以自定義timestamp的默認值和NULLABLE屬性,mysql不再會自作主張的給你自動設置。

另外此參數在8.0.11中提示已經要逐步棄用(轉為內部默認配置)。
最后:雖然5.6.6之后可以通過設置explicit_defaults_for_timestamp來改變timestamp的設置模式,但還是推薦用datetime,explicit_defaults_for_timestamp默認為on已經是8.0以后的事了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM