一、核心区别对比图(建议收藏)

  特性

  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;三、核心决策流程图

  1. 是否需要时区感知?→ 是 → TIMESTAMP
  2. 时间跨度超过2038年?→ 是 → DATETIME
  3. 仅需时间部分?→ TIME
  4. 仅需年份?→ YEAR
  5. 其他情况 → 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