時間類型選型直接影響跨時區應用正確性、歷史資料相容性與維護成本。本文從儲存原理、時區轉換、範圍差異、自動屬性四大維度深度解析,助你做出正確選擇。
MySQL 提供多種等效函數:
CURRENT_TIMESTAMP / CURRENT_TIMESTAMP()NOW()LOCALTIME / LOCALTIME() / LOCALTIMESTAMP / LOCALTIMESTAMP()| 特性 | TIMESTAMP | DATETIME |
|---|---|---|
| 寫入時 | 將會話時區時間轉為 UTC 儲存 | 原樣儲存,不做時區轉換 |
| 讀取時 | 從 UTC 轉為會話時區返回 | 原樣返回 |
| 跨時區一致性 | ✅ 自動轉換 | ❌ 需應用層處理 |
-- 建表 CREATE TABLE test_ts (id INT, hiredate TIMESTAMP); CREATE TABLE test_dt (id INT, hiredate DATETIME); -- 插入同一時間 INSERT INTO test_ts VALUES (1, '2015-12-08 00:00:00'); INSERT INTO test_dt VALUES (1, '2015-12-08 00:00:00'); -- 修改會話時區為 UTC SET time_zone = '+0:00'; -- 查詢結果 SELECT * FROM test_ts; -- 2015-12-07 16:00:00 (提前 8 小時,CST→UTC) SELECT * FROM test_dt; -- 2015-12-08 00:00:00 (不變)
結論:跨時區業務必選 TIMESTAMP;單時區、歷史歸檔、需保留原始輸入時間選 DATETIME。
| 類型 | 最小值 | 最大值 |
|---|---|---|
| TIMESTAMP | '1970-01-01 00:00:01' UTC | '2038-01-19 03:14:07' UTC (2038 年問題) |
| DATETIME | '1000-01-01 00:00:00' | '9999-12-31 23:59:59' |
MySQL 5.6.5 前:僅首個 TIMESTAMP 欄位預設 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,且限一個欄位。
5.6.5+:TIMESTAMP/DATETIME 均支援,無數量限制。
CREATE TABLE t (id INT, ts TIMESTAMP); INSERT INTO t(id) VALUES (1); -- 未給 ts 值 -- 實際執行:ts 自動填入 CURRENT_TIMESTAMP -- SHOW CREATE TABLE 顯示:ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
SET explicit_defaults_for_timestamp = ON;ts TIMESTAMP DEFAULT '0000-00-00 00:00:00'ts TIMESTAMP NULL(預設值變為 NULL)