理解 MySQL 時間類型的物理存儲格式,不僅有助於優化存儲空間,更能在數據遷移、異構同步、底層調試場景中發揮關鍵作用。本文通過實際十六進制內存示例,深度剖析四大核心時間類型的字節佈局與編碼邏輯。
行數據中直接存儲 4 字節無符號整數,代表 UTC 1970-01-01 00:00:00 起的秒數。時區轉換發生在讀寫交互層:寫入時將會話時區時間轉為 UTC 存儲;讀取時再按會話時區轉回。這也是其「時區感知」特性的根源。
1970-01-01 00:00:01 至 2038-01-19 03:14:07(32 位有符號整數上限)。TIMESTAMP(6)),擴展至 4+3 字節。以 3 字節(24 位)存儲,按位分配:
第 1-5 位:日期 (1-31)
第 6-9 位:月份 (1-12)
第 10-23 位:年份 (0-9999,實際存儲值 = 年份 - 1900?實測為直接存儲年份值)
實戰解碼示例(GDB 內存輸出):
buf[30] = 33 (0x21) -> 0010 0001
buf[31] = -73 (0xB9) -> 1011 1001
buf[32] = 15 (0x0F) -> 0000 1111
組合為 24 位二進制:0000 1111 1011 1001 0010 0001
00001 = 1 → 日期1001 = 9 → 月份000011111011 = 2011 → 年份存儲範圍:1000-01-01 至 9999-12-31,無時區概念。
單字節存儲,值 = 年份 - 1900。
示例:
buf[33] = 112 (0x70) -> 112 + 1900 = 2012
MySQL 8.0 已移除 YEAR(2) 格式,統一為 YEAR(等同 YEAR(4)),範圍 1901-2155。
MySQL 5.6.4 前為固定 8 字節,5.6.4+ 支持小數秒(最多 6 位)擴展存儲。舊版編碼邏輯為將 YYYYMMDDHHMMSS 作為一個大整數按大端序存儲。
實戰解碼示例(輸入 2011-08-27 19:32:46):
buf[30] = -98 (0x9E)
buf[31] = 3 (0x03)
buf[32] = -74 (0xBA)
buf[33] = 106 (0x6A)
buf[34] = 74 (0x4A)
buf[35] = 18 (0x12)
buf[36] = 0 (0x00)
buf[37] = 0 (0x00)
按大端序組合計算:
(256-98) + 3×256 + (256-74)×256² + 106×256³ + 74×256⁴ + 18×256⁵
= 158 + 768 + 182×65536 + 106×16777216 + 74×4294967296 + 18×1099511627776
= 20110827193246
完美還原 YYYYMMDDHHMMSS 格式。新版(5.6.4+)採用更高效的打包格式:日期時間部分 5 字節 + 小數秒 0-3 字節,節省空間並提升比較性能。
| 類型 | 字節數 | 時區感知 | 範圍 | 適用場景 |
|---|---|---|---|---|
| TIMESTAMP | 4 (含小數秒 +3) | 是 | 1970-2038 | 記錄修改時間、跨時區應用 |
| DATETIME | 5-8 | 否 | 1000-9999 | 業務原始時間、需保留本地時間含義 |
| DATE | 3 | 否 | 1000-9999 | 生日、紀念日等純日期 |
| YEAR | 1 | 否 | 1901-2155 | 年份維度統計 |
掌握底層存儲細節,能讓你在設計表結構、排查數據異常、進行跨版本升級時更具洞察力。選對時間類型,是數據建模的基本功。