核心機制
TIMESTAMP 欄位可設定 DEFAULT CURRENT_TIMESTAMP 及 ON UPDATE CURRENT_TIMESTAMP,實現建立時間/更新時間自動維護,無需應用層干預。
建表範例
CREATE TABLE `article` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) NOT NULL,
`content` LONGTEXT,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
關鍵限制:每表僅一個自動 TIMESTAMP (5.6.5 前)
MySQL 5.6.5 以前:一個表僅能有一個 TIMESTAMP 欄位使用 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP。
MySQL 5.6.5+:移除此限制,可多欄位自動初始化/更新。
版本差異與兼容性
| 版本 | 支援多自動 TIMESTAMP | 顯式 DEFAULT NULL 行為 | 時區處理 |
| 5.5 | 否 | 插入 NULL → 當前時間 | 系統時區 |
| 5.6.5+ | 是 | 需顯式 DEFAULT NULL 才存 NULL | 支援 time_zone 會話變數 |
| 8.0 | 是 | 同 5.6.5+ | 支援 TIMESTAMP WITH TIME ZONE (預覽) |
TIMESTAMP vs DATETIME 選型
| 特性 | TIMESTAMP | DATETIME |
| 範圍 | 1970-01-01 ~ 2038-01-19 (32位有號秒) | 1000-01-01 ~ 9999-12-31 |
| 儲存大小 | 4 位元組 | 5 位元組 (5.6.4 前 8 位元組) |
| 時區轉換 | 存儲 UTC,讀取轉會話時區 | 原樣存儲,無轉換 |
| 自動初始化/更新 | 原生支援 | 5.6.5+ 支援 |
| 適用場景 | 建立/更新時間、日誌、跨時區應用 | 生日、排程、歷史日期、超出 2038 年 |
最佳實踐建議
- 新專案 (5.6.5+):
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP、updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- 舊版本/需存 NULL:
created_at DATETIME DEFAULT CURRENT_TIMESTAMP (5.6.5+),應用層設定 updated_at
- 跨時區系統:統一儲存 UTC,應用層轉換顯示;或全用
DATETIME 存 UTC 避免 2038 年問題
- 避免隱式轉換:連線字串指定
serverTimezone=UTC (JDBC) / SET time_zone = '+00:00'