萬盛學電腦網

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

MySQL DATETIME vs TIMESTAMP 深度解析:儲存、範圍、時區、預設值三大差異

兩類型顯示格式相同(YYYY-MM-DD HH:MM:SS),但底層機制截然不同。選錯類型會導致跨時區資料錯誤、年份溢位或預設值行為不符預期。

核心差異對照表

特性DATETIMETIMESTAMP
儲存大小8 Bytes4 Bytes
支援範圍1000-01-01 ~ 9999-12-311970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC
儲存方式字面值(YYYY-MM-DD HH:MM:SS)Unix Timestamp(UTC 秒數)
時區轉換無,存什麼讀什麼有,寫入轉 UTC,讀出轉回 Session 時區
預設值可設 NULL 或固定值預設 NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
年份 2038 問題無有(32 位元秒數上限)

TIMESTAMP 顯示寬度(已棄用)

舊版支援 TIMESTAMP(14)、TIMESTAMP(8) 等顯示寬度,MySQL 8.0 已移除,統一完整顯示。

實務選型指南

  1. 跨時區應用、記錄操作時間、审計日誌 → TIMESTAMP
  2. 出生日期、預約時間、歷史事件、需儲存 2038 年後 → DATETIME
  3. 自動記錄建立/更新時間:
    CREATE TABLE `t` (
      `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    );

時間比較最佳實踐

避免 字串直接比較:

-- 避免
WHERE `dt` > '2023-01-01 12:00:00'

推薦 使用函數明確轉換:

-- 方法 1:UNIX_TIMESTAMP(明確秒數比較)
WHERE UNIX_TIMESTAMP(`dt`) > UNIX_TIMESTAMP('2023-01-01 12:00:00')

-- 方法 2:BETWEEN(利用索引範圍掃描)
WHERE `dt` BETWEEN '2023-01-01 12:00:00' AND '2023-01-01 13:00:00'

-- 方法 3:DATE() 擷取日期部分(會失效索引,慎用)
WHERE DATE(`dt`) = '2023-01-01'

版本演進提醒

  • MySQL 5.6.4+:DATETIME 支援 DEFAULT CURRENT_TIMESTAMP 及 ON UPDATE
  • MySQL 8.0:移除 TIMESTAMP(N) 顯示寬度語法

理解儲存機制與時區行為,才能在分散式系統中正確處理時間資料。

copyright © 萬盛學電腦網 all rights reserved