MySQL 提供多個函數獲取當前時間戳:
CURRENT_TIMESTAMP / CURRENT_TIMESTAMP()NOW()LOCALTIME / LOCALTIME()LOCALTIMESTAMP / LOCALTIMESTAMP()以上函數在同一條 SQL 內多次調用返回值相同(語句級一致性)。
| 類型 | 格式 | 儲存範圍 | 時區轉換 | 儲存字節 |
|---|---|---|---|---|
| DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 無 | 3 bytes |
| TIME | HH:MM:SS[.fraction] | -838:59:59 ~ 838:59:59 | 無 | 3 bytes |
| DATETIME | YYYY-MM-DD HH:MM:SS[.fraction] | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 無(原樣存取) | 5 bytes (5.6.4+) / 8 bytes |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS[.fraction] | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | 有(寫入轉 UTC,讀取轉會話時區) | 4 bytes (5.6.4+) / 8 bytes |
CREATE TABLE test_ts (id INT, hiredate TIMESTAMP); CREATE TABLE test_dt (id INT, hiredate DATETIME); INSERT INTO test_ts VALUES (1, '20151208000000'); INSERT INTO test_dt VALUES (1, '20151208000000');
mysql> SHOW VARIABLES LIKE '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | CST | | time_zone | SYSTEM | +------------------+--------+ mysql> SET time_zone = '+00:00'; -- UTC mysql> SELECT * FROM test_ts; +------+---------------------+ | id | hiredate | +------+---------------------+ | 1 | 2015-12-07 16:00:00 | -- 提前 8 小時(CST=UTC+8) +------+---------------------+ mysql> SELECT * FROM test_dt; +------+---------------------+ | id | hiredate | +------+---------------------+ | 1 | 2015-12-08 00:00:00 | -- 不變 +------+---------------------+
結論: TIMESTAMP 寫入時將會話時區時間轉為 UTC 儲存;讀取時再轉回目標會話時區。DATETIME 僅原樣存取。
CREATE TABLE test (id INT, hiredate TIMESTAMP); INSERT INTO test (id) VALUES (1); -- 未給 hiredate 值 SELECT * FROM test; +------+---------------------+ | id | hiredate | +------+---------------------+ | 1 | 2015-12-08 14:34:46 | -- 自動填入當前時間 SHOW CREATE TABLE test\G -- 實際 DDL 含隱式屬性: -- `hiredate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
規則:首個 TIMESTAMP 欄位 若未顯式指定 DEFAULT/ON UPDATE,自動獲得:
DEFAULT CURRENT_TIMESTAMP(自動初始化)ON UPDATE CURRENT_TIMESTAMP(自動更新)方法一:全域參數 SET GLOBAL explicit_defaults_for_timestamp = ON;(5.6.6+)
方法二(參數保持 OFF 時):
DEFAULT 值:hiredate TIMESTAMP DEFAULT '2000-01-01'hiredate TIMESTAMP NULL → 預設 NULL,無自動屬性DEFAULT 0:hiredate TIMESTAMP DEFAULT 0 → 零值CREATE TABLE test1 (id INT, hiredate TIMESTAMP NULL); SHOW CREATE TABLE test1\G -- `hiredate` timestamp NULL DEFAULT NULL CREATE TABLE test2 (id INT, hiredate TIMESTAMP DEFAULT 0); SHOW CREATE TABLE test2\G -- `hiredate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
| 場景 | 推薦類型 | 理由 |
|---|---|---|
| 跨時區應用(全球用戶) | TIMESTAMP | 自動時區轉換,儲存統一 UTC |
| 歷史資料/出生日期/未來排程 | DATETIME | 範圍大(1000~9999 年),無時區副作用 |
| 審計日誌/操作記錄 | TIMESTAMP + 自動更新 | 自動記錄建立/修改時間 |
| 需精確保留原始輸入時間 | DATETIME | 不受會話時區影響 |
SYSDATE() 非語句級一致:主從複制不安全,啟用 --sysdate-is-now 或改用 NOW()。DEFAULT 0 存入 '0000-00-00 00:00:00',部分驅動程式無法解析,建議用 NULL 或明確預設值。