MySQL 5.6.6 版本對 TIMESTAMP 資料型別的預設行為進行了重大調整,這項變更雖然旨在讓行為更符合標準 SQL 規範,但也導致許多既有應用在升級時遭遇警告甚至錯誤。本文將詳細梳理 5.6.6 版本前後的行為差異,並說明如何透過 explicit_defaults_for_timestamp 參數平滑過渡。
在舊版本中,TIMESTAMP 欄位擁有一套獨特且常令人困惑的隱性預設規則:
NULL 屬性,TIMESTAMP 欄位預設為 NOT NULL(這與其他資料型別預設允許 NULL 形成鮮明對比)。NULL 時,系統會自動將其轉換為當前時間戳記(CURRENT_TIMESTAMP)。資料表中的第一個 TIMESTAMP 欄位,若未宣告 NULL、DEFAULT 或 ON UPDATE 子句,會自動獲得以下屬性:
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
這意味著該欄位在插入時自動記錄建立時間,更新時自動刷新為最新時間。
從第二個 TIMESTAMP 欄位開始,若未宣告 NULL 或 DEFAULT,預設值會被設為 '0000-00-00 00:00:00'(零時間)。插入資料時若未指定該欄位值,同樣會填入零時間,且不會產生任何警告。


自 5.6.6 版本起,上述隱性預設行為被標記為 Deprecated(棄用)。啟動 MySQL 時會輸出如下警告:
[Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
在 my.cnf 的 [mysqld] 區段加入以下參數並重啟服務:
[mysqld] explicit_defaults_for_timestamp=true
explicit_defaults_for_timestamp 後的新規則NOT NULL 的 TIMESTAMP 欄位現在允許 NULL 值,寫入 NULL 不再自動轉換為當前時間。TIMESTAMP 欄位不再自動獲得 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP。NOT NULL 但未指定 DEFAULT 的欄位,不再擁有隱性預設值。在嚴格 SQL 模式下插入資料若未賦值會報錯;非嚴格模式下會寫入零時間並發出警告(行為與 DATETIME 等其他時間型別一致)。

SHOW CREATE TABLE 檢查所有 TIMESTAMP 欄位是否依賴隱性預設值。DEFAULT CURRENT_TIMESTAMP、ON UPDATE CURRENT_TIMESTAMP、NULL 或 NOT NULL,避免歧義。explicit_defaults_for_timestamp 並跑完整測試套件,確認應用層邏輯不受影響。核心觀念:
explicit_defaults_for_timestamp的本意是「強制開發者為 TIMESTAMP 欄位顯式指定預設行為」,消除隱性魔法,讓資料庫行為更可預測、更易維護。