核心限制
MySQL 不支援 `DEFAULT NOW()` 或 `DEFAULT CURRENT_TIMESTAMP` 於 DATETIME/DATE 欄位(5.6.5 前)。解決方案:使用 TIMESTAMP 或升級至 5.6.5+ 使用 DATETIME DEFAULT CURRENT_TIMESTAMP。
TIMESTAMP 完整特性表
| 定義 | 顯示格式 | 儲存精度 | 備註 |
| TIMESTAMP(14) | YYYYMMDDHHMMSS | 14 位 | 完整格式 |
| TIMESTAMP(8) | YYYYMMDD | 14 位 | 只顯示日期 |
| TIMESTAMP(0) | → 強制 14 | 14 位 | 0/>14 皆為 14 |
| 奇數長度 | → 下一偶數 | 14 位 | 1→2, 5→6 |
關鍵:無論顯示長度,實際儲存皆為 14 位完整精度。`ALTER TABLE` 擴展顯示長度可「找回」隱藏的時分秒。
自動更新規則(僅第一個 TIMESTAMP 欄位)
INSERT 未指定該欄位值
LOAD DATA INFILE 未提供該欄位
UPDATE 修改了其他欄位,且未顯式設定該 TIMESTAMP
- 顯式設定為
NULL 或 NOW()
多 TIMESTAMP 欄位控制
CREATE TABLE t (
id INT PRIMARY KEY,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 建立時間(僅 INSERT)
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新時間
);
MySQL 5.6.5+ 以上寫法標準化,舊版僅第一個 TIMESTAMP 擁有自動特性,第二個需觸發器或應用層維護。
格式化輸出
SELECT
id,
DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') AS create_time,
DATE_FORMAT(update_time, '%Y-%m-%d') AS update_date
FROM t;
日期類型轉換陷阱
| 來源 → 目標 | 結果 |
| DATE → DATETIME/TIMESTAMP | 時間部份補 00:00:00 |
| DATETIME/TIMESTAMP → DATE | 截斷時間部份 |
| '1968-01-01' → TIMESTAMP | 非法 → 變 0 (1970 前) |
| 2 位數年份 | 00-69 → 2000-2069, 70-99 → 1970-1999 |
最佳實踐建議
- MySQL 5.6.5+:優先用
DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)(微秒精度、無 2038 年問題)
- 舊版:第一欄
TIMESTAMP DEFAULT CURRENT_TIMESTAMP 當建立時間,更新時間用觸發器
- 應用層明確傳遞時間,避免依賴伺服器時區
- 時區統一用 UTC 儲存,顯示層轉換
- 上一篇文章: 從 MySQL 原生 API 遷移至 ADODB:資料庫抽象層實戰指南
- 下一篇文章: MySQL 權限系統深度解析:用戶認證、主機匹配、權限表結構與最佳實踐
Copyright ©
程式碼之家 All Rights Reserved