MySQL 5.6.5 之前版本:不支援將函數(如 NOW()、CURRENT_TIMESTAMP)直接作為欄位預設值(`DEFAULT` 子句),僅允許常數值。
| 版本 | 支援情況 |
|---|---|
| < 5.6.5 | 僅 TIMESTAMP 型別可用 DEFAULT CURRENT_TIMESTAMP;DATETIME、DATE 均不支援函數預設值 |
| 5.6.5+ | DATETIME、TIMESTAMP、DATE 均支援 DEFAULT CURRENT_TIMESTAMP 及 ON UPDATE CURRENT_TIMESTAMP |
| 8.0.13+ | 進一步支援 DEFAULT (expr) 語法,允許任意非決定性函數(如 UUID()、NOW())作為預設值 |
CREATE TABLE t (
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
缺點:TIMESTAMP 範圍 1970-2038,受時區影響,5.6.6 前一張表僅能有一個自動更新的 TIMESTAMP 欄位。
-- 應用程式插入時顯式指定
INSERT INTO t (create_time) VALUES (NOW());
-- 或由 ORM/框架自動填充(如 Hibernate @CreationTimestamp、MyBatis Plus fillStrategy)
優點:邏輯集中、跨資料庫可移植、避免觸發器效能開銷。
CREATE TRIGGER t_bi BEFORE INSERT ON t
FOR EACH ROW
BEGIN
IF NEW.create_time IS NULL THEN
SET NEW.create_time = NOW();
END IF;
IF NEW.update_time IS NULL THEN
SET NEW.update_time = NOW();
END IF;
END;
缺點:增加寫入延遲、維護成本高、複雜業務易出錯。
CREATE TABLE orders (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
-- 8.0.13+ 更多彈性
trace_id CHAR(36) DEFAULT (UUID()) COMMENT '追蹤 ID'
);
DEFAULT NOW() 在舊版會報錯 Invalid default value for 'col'。CURRENT_TIMESTAMP 與 NOW() 語義相同,但前者為標準 SQL 關鍵字,移植性更好。ON UPDATE CURRENT_TIMESTAMP 僅在 UPDATE 實際修改該行時觸發,REPLACE、INSERT ... ON DUPLICATE KEY UPDATE 亦會觸發。TIMESTAMP 值不同步,建議統一使用 DATETIME + 應用層寫入 UTC 時間。舊版 MySQL 確實不支援 DEFAULT NOW(),但透過 TIMESTAMP、應用層賦值、觸發器均可解決。現代版本(5.6.5+)已原生支援 DATETIME DEFAULT CURRENT_TIMESTAMP,8.0 更開放任意運算式。**強烈建議升級至 8.0 並採用原生語法**,簡潔且效能最優。