MySQL TIMESTAMP 型別具有自動初始化與自動更新的隱含特性,這與 DATETIME 截然不同。若不理解其預設行為,極易導致「建立時間」欄位在更新記錄時被覆蓋為最新時間。
| 定義方式 | INSERT 時 | UPDATE 時 | 適用場景 |
|---|---|---|---|
| 無任何屬性 | CURRENT_TIMESTAMP | CURRENT_TIMESTAMP | 更新時間 |
DEFAULT CURRENT_TIMESTAMP | CURRENT_TIMESTAMP | 不變 | 建立時間 |
ON UPDATE CURRENT_TIMESTAMP | 0 (零值) | CURRENT_TIMESTAMP | 更新時間(需手動給初值) |
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | CURRENT_TIMESTAMP | CURRENT_TIMESTAMP | 建立+更新時間 |
DEFAULT '2020-01-01'(常數) | 常數值 | 不變 | 固定初始時間 |
DEFAULT '2020-01-01' ON UPDATE CURRENT_TIMESTAMP | 常數值 | CURRENT_TIMESTAMP | 固定建立+自動更新 |
| 特性 | TIMESTAMP | DATETIME |
|---|---|---|
| 儲存空間 | 4 bytes | 8 bytes (5.6.4 前) / 5 bytes (5.6.4+) |
| 時間範圍 | 1970-01-01 ~ 2038-01-19 (UTC) | 1000-01-01 ~ 9999-12-31 |
| 時區轉換 | 儲存為 UTC,讀取轉為會話時區 | 不轉換,原樣儲存 |
| 自動屬性 | 支援 | 5.6.5+ 支援 DEFAULT CURRENT_TIMESTAMP |
| 索引效能 | 略優(較小) | 標準 |
DATETIME DEFAULT CURRENT_TIMESTAMP(MySQL 5.6.5+)或 TIMESTAMP DEFAULT CURRENT_TIMESTAMP(僅 INSERT 時賦值)。DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(5.6.5+)或 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。DATETIME 並統一在應用層處理時區,避免 TIMESTAMP 時區轉換造成的困擾。DEFAULT 与 ON UPDATE 子句,不要依賴版本差異的隱式行為。CREATE TABLE `article` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(200) NOT NULL, `content` TEXT, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。explicit_defaults_for_timestamp=ON:MySQL 5.6.6+ 引入此變數,啟用後關閉舊版隱式預設行為,建議開啟以獲得一致行為。ON UPDATE CURRENT_TIMESTAMP 無 DEFAULT 時,INSERT 不給值會寫入 0000-00-00 00:00:00,需注意 sql_mode 中的 NO_ZERO_DATE。TIMESTAMP 的自動更新特性雖方便,但隱含行為複雜且受版本、sql_mode、時區影響大。現代應用建議統一使用 DATETIME 並顯式指定 DEFAULT/ON UPDATE,配合應用層時區處理,獲得可預期、可維護的時間欄位管理。