萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL TIMESTAMP 自動更新機制詳解與創建時間陷阱避坑

核心結論

TIMESTAMP 默認行為:INSERT 和 UPDATE 都會自動刷新為當前時間。 若需記錄「創建時間」,請使用 DATETIME + NOW() 或顯式指定 DEFAULT CURRENT_TIMESTAMP 且不帶 ON UPDATE。

四種定義模式對照

定義語法INSERT 行為UPDATE 行為適用場景
TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP當前時間自動刷新最後修改時間
TIMESTAMP DEFAULT CURRENT_TIMESTAMP當前時間**不變**創建時間(推薦)
TIMESTAMP ON UPDATE CURRENT_TIMESTAMP0000-00-00 00:00:00自動刷新極少用
TIMESTAMP DEFAULT '2000-01-01'固定默認值不變業務默認值

實測驗證

-- 表 t1:雙向自動更新
CREATE TABLE t1 (
    p_c INT NOT NULL,
    p_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;

INSERT INTO t1(p_c) VALUES (1);  -- p_time = 當前時間
UPDATE t1 SET p_c = 2 WHERE p_c = 1;  -- p_time 刷新為最新時間

-- 表 t2:僅 INSERT 自動賦值
CREATE TABLE t2 (
    p_c INT NOT NULL,
    p_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

INSERT INTO t2(p_c) VALUES (1);  -- p_time = 當前時間
UPDATE t2 SET p_c = 2 WHERE p_c = 1;  -- p_time **保持不變**

關鍵限制:一張表只能有一個「雙向自動」 TIMESTAMP

-- 錯誤:兩個列都有 DEFAULT CURRENT_TIMESTAMP
CREATE TABLE t3 (
    t1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    t2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP  -- ERROR 1293
);

-- 正確:第二列顯式指定默認值為零或常量
CREATE TABLE t3 (
    t1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    t2 TIMESTAMP DEFAULT '0000-00-00 00:00:00'
);

5.6.5+ 版本新特性:DATETIME 也支持自動初始化/更新

CREATE TABLE t4 (
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

**推薦做法**:5.6.5+ 直接用 DATETIME 記錄創建/更新時間,語義清晰、無時區轉換、範圍更大(1000-9999 年)。

時區陷阱

  • TIMESTAMP 存儲為 UTC,讀取時按會話時區轉換
  • DATETIME 存儲原始值,不做時區轉換
  • 跨時區應用優先用 DATETIME 或統一應用層時區

最佳實踐總結

  1. 創建時間:created_at DATETIME DEFAULT CURRENT_TIMESTAMP(5.6.5+)或 TIMESTAMP DEFAULT CURRENT_TIMESTAMP(舊版)
  2. 更新時間:updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(5.6.5+)或 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  3. 應用層顯式寫入 NOW() 覆蓋默認行為時,確保時區一致
copyright © 萬盛學電腦網 all rights reserved