| 特性 | DATETIME | TIMESTAMP |
|---|---|---|
| 存儲字節 | 8 bytes (5.6.4 前) / 5 bytes + 小數秒 (5.6.4+) | 4 bytes (5.6.4 前) / 4 bytes + 小數秒 (5.6.4+) |
| 時間範圍 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC |
| 時區感知 | 無 (存儲字面值) | 有 (存儲 UTC,讀取按會話時區轉換) |
| 自動初始化/更新 | 5.6.5+ 支持 DEFAULT CURRENT_TIMESTAMP / ON UPDATE CURRENT_TIMESTAMP | 首個 TIMESTAMP 列默認自動初始化/更新,可顯式控制 |
| NULL 值處理 | 不自動賦值 | 插入 NULL 等同於 CURRENT_TIMESTAMP |
| Java 映射 | java.sql.Timestamp / java.time.LocalDateTime | java.sql.Timestamp / java.time.Instant |
| 索引/查詢性能 | 略低 (佔用空間大) | 略高 (佔用空間小) |
-- 會話時區為 +08:00
INSERT INTO t(ts_col) VALUES ('2024-01-01 12:00:00'); -- 存儲為 UTC: 2024-01-01 04:00:00
SELECT ts_col FROM t; -- 讀出顯示: 2024-01-01 12:00:00 (按會話時區轉回)
-- 若會話時區變為 +00:00 再查
SET time_zone = '+00:00';
SELECT ts_col FROM t; -- 顯示: 2024-01-01 04:00:00 <-- 數據「變了」!
結論:跨時區應用、數據遷移、備份恢復時,TIMESTAMP 會隨時區變化而「變值」,DATETIME 絕不變。需業務無時區敏感性才用 TIMESTAMP。
32 位有符號整數存儲秒數,上限 2038-01-19。長期項目(銀行、保單、日志審計)**禁用 TIMESTAMP 作為業務時間**,必須用 DATETIME 或 BIGINT 毫秒時間戳。
DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP,且二擇一DEFAULT CURRENT_TIMESTAMP + ON UPDATE CURRENT_TIMESTAMP 可共存DATETIME(3) / TIMESTAMP(3)created_at、updated_at,邏輯清晰可控--tz-utc 參數