MySQL 5.5 升級 5.6 TIMESTAMP 行為變更兼容指南
MySQL 5.6 重構了 TIMESTAMP 隱式預設值行為,升級後易觸發「資料截斷」、「預設值不符」、「應用層報錯」。本文對比 5.5/5.6 差異、explicit_defaults_for_timestamp 參數控制、升級驗證清單。
5.5 vs 5.6 TIMESTAMP 行為對比
| 行為 | MySQL 5.5 | MySQL 5.6+ |
| 首個無顯式預設的 TIMESTAMP NOT NULL | 隱式 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | **無隱式預設**(受參數控制) |
| 後續無顯式預設的 TIMESTAMP NOT NULL | 隱式 DEFAULT '0000-00-00 00:00:00' | **無隱式預設** |
| 插入 NULL 值 | 自動轉為 CURRENT_TIMESTAMP | **報錯**(除非顯式 DEFAULT NULL) |
| 多欄位 CURRENT_TIMESTAMP | 不支援,報錯 | **支援** |
關鍵參數:explicit_defaults_for_timestamp
| 值 | 行為 | 備註 |
| OFF (0) | 兼容 5.5:保留隱式預設值 | 啟動報 Warning:TIMESTAMP with implicit DEFAULT value is deprecated |
| ON (1) | 標準 SQL:移除隱式預設,需顯式指定 | **推薦**,未來版本預設將為 ON 並移除參數 |
升級實戰驗證清單
- 檢查現有表結構:
SELECT TABLE_NAME, COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, EXTRA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE='timestamp' AND TABLE_SCHEMA='your_db';
- 補全顯式預設值(建議在升級前完成):
-- 需自動更新時間戳
ALTER TABLE t MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
-- 僅建立時寫入
ALTER TABLE t MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- 允許 NULL
ALTER TABLE t MODIFY optional_ts TIMESTAMP NULL DEFAULT NULL;
- 應用層檢查:確認 INSERT/UPDATE 語句未依賴隱式預設(如傳 NULL 期望自動填充)。
- 測試環境先行升級:跑全量回歸測試,重點驗證時間欄位寫入/讀取。
- 生產升級窗口:設定
explicit_defaults_for_timestamp=0 平滑過渡,觀察錯誤日誌無異常後,排期遷移為 =1。
避坑指南
- ❌ 升級後直接設
=1 未補全預設值 → 大量 Field 'ts' doesn't have a default value 報錯。
- ❌ 應用傳 NULL 給 NOT NULL TIMESTAMP → 5.5 自動填充,5.6+ 報錯。
- ❌ 忽略
0000-00-00 零日期值 → 5.6+ NO_ZERO_DATE SQL_MODE 下報錯。
- ✅ 統一遷移至顯式
DEFAULT CURRENT_TIMESTAMP 寫法,不依賴隱式行為。
- ✅ 新建表強制規範:所有 TIMESTAMP 欄位**必須**顯式聲明 DEFAULT/NULL/NOT NULL。