| 特性 | DATE | DATETIME | TIMESTAMP |
|---|---|---|---|
| 顯示格式 | YYYY-MM-DD | YYYY-MM-DD HH:mm:ss | YYYY-MM-DD HH:mm:ss |
| 時間範圍 | 1000-01-01 ~ 9999-12-31 | 1000-01-01 ~ 9999-12-31 | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 (UTC) |
| 時區處理 | 無 | 無 | 存儲轉 UTC,讀取轉當前時區 |
| 自動更新 | 不支援 | 不支援 | 支援 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
| 精度 | 天 | 秒 | 秒 |
| 儲存空間 | 3 bytes | 8 bytes (5.6.4 前) / 5 bytes + 小數秒 | 4 bytes |
現象:插入數據後修改 MySQL 時區,讀取時時間發生偏移。
原因:TIMESTAMP 存儲時轉為 UTC,讀取時按當前會話時區轉回。時區變更導致換算基準改變。
對比:DATE/DATETIME 存儲「字面值」,不受時區影響。
建議:跨時區應用優先用 DATETIME,或在應用層統一處理時區轉換。
TIMESTAMP 受 32 位有符號整數限制,最大值為 2038-01-19。長期項目(如合同、壽險)禁用 TIMESTAMP,改用 DATETIME 或 BIGINT 存儲毫秒級時間戳。
MySQL 允許 '13-6-5'、'13:6:5' 等非標準格式,但:
'13:16:5' 會被誤判為無效,寫入 0000-00-00 00:00:00 並報警告。鐵律:永遠使用標準格式 'YYYY-MM-DD HH:mm:ss' 進行讀寫。
| 場景 | 推薦類型 | 理由 |
|---|---|---|
| 生日、入職日期等純日期 | DATE | 節省空間,語義清晰 |
| 訂單創建、日誌記錄、審計追蹤 | DATETIME | 範圍大、無時區副作用、支援 2038 年後 |
| 記錄「最後修改時間」自動維護 | TIMESTAMP | 利用自動更新特性,簡化應用代碼 |
| 高併發、需毫秒精度、跨時區系統 | BIGINT (Unix 毫秒時間戳) | 應用層完全可控,效能最高,無年份上限 |
理解三類型的底層存儲與轉換機制,是避免時間相關 Bug 的關鍵。現代架構傾向於應用層統一使用 UTC 毫秒長整數,數據庫層僅作持久化,最大程度消除時區與年份邊界問題。