一、核心区别对比图(建议收藏)
特性 | DATETIME | TIMESTAMP |
存储空间 | 8字节 | 4字节 |
时间范围 | 1000-01-01 至 9999-12-31 | 1970-01-01 至 2038-01-19 |
时区处理 | 无转换 | 自动UTC转换 |
默认值行为 | 需显式设置 | 支持自动初始化和更新 |
二、典型场景代码实战
1. DATE类型使用示例
-- 创建表CREATE TABLE birthdays ( id INT PRIMARY KEY AUTO_INCREMENT, user_name VARCHAr(50), birth_date DATE NOT NULL);-- 插入数据INSERT INTO birthdays (user_name, birth_date)VALUES ('张三', '1990-05-20');-- 查询当月生日SELECt * FROM birthdays WHERe MonTH(birth_date) = MonTH(CURDATE());2. TIMESTAMP自动更新演示
-- 创建表(自动维护created_at/updated_at)CREATE TABLE articles ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAr(255), content TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);-- 插入数据(无需指定时间字段)INSERT INTO articles (title, content) VALUES ('MySQL技巧', '本文讲解DATETIME/TIMESTAMP区别');-- 更新数据(updated_at自动更新)UPDATE articles SET content = '新增时区处理说明' WHERe id=1;3. 时区敏感操作演示
-- 查看当前时区SELECT @@global.time_zone, @@session.time_zone;-- 设置会话时区为东京SET TIME_ZONE = '+09:00';-- 插入时间戳数据INSERT INTO timezone_test (ts) VALUES ('2023-01-01 12:00:00');-- 切换回系统时区查看差异SET TIME_ZONE = SYSTEM;SELECT ts, CONVERT_TZ(ts, '+09:00', @@session.time_zone) AS local_ts FROM timezone_test;三、核心决策流程图
- 是否需要时区感知?→ 是 → TIMESTAMP
- 时间跨度超过2038年?→ 是 → DATETIME
- 仅需时间部分?→ TIME
- 仅需年份?→ YEAR
- 其他情况 → DATE/DATETIME
四、性能优化建议
-- 索引优化(针对时间范围查询)ALTER TABLE logs ADD INDEX idx_created_at (created_at);-- 批量插入优化SET autocommit = 0;INSERT INTO big_table (event_time) SELECt '2023-01-01 00:00:00' + INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY FROM (SELECT 0 AS a UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3) aCROSS JOIN (SELECT 0 AS a UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3) bCROSS JOIN (SELECT 0 AS a UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3) c;COMMIT;五、常见坑点对照表
问题现象 | 根本原因 | 解决方案 |
TIMESTAMP插入未来时间报错 | 超过2038-01-19 03:14:07 | 改用DATETIME类型 |
时区切换后时间错误 | TIMESTAMP自动时区转换 | 统一时区配置或使用CONVERT_TZ() |
自动更新未生效 | 未设置ON UPDATE CURRENT_TIMESTAMP | ALTER TABLE ... MODIFY COLUMN ... ON UPDATE CURRENT_TIMESTAMP |
