技术科普
数据库怎么存时间?DATETIME与TIMESTAMP的区别
数据库中的时间字段如何存储,直接影响系统在跨时区场景下的正确性。不同数据库、不同字段类型的行为差异很大。
MySQL:DATETIME与TIMESTAMP
这是最常被混淆的一对:
- DATETIME:存储字面值,不随时区变化。写入什么就存什么,取出也不变。范围大(1000–9999年)
- TIMESTAMP:内部以UTC存储,写入和读取时按会话时区转换。范围较小(约1970–2038年)
举例:会话时区为+08:00时写入 2027-08-28 12:00:00 到 TIMESTAMP,实际存的是UTC的04:00;换成UTC会话查询,显示 2027-08-28 04:00:00。
PostgreSQL:timestamp与timestamptz
timestamp(without time zone):不带时区,存字面值timestamptz(with time zone):按UTC存储,显示时转会话时区
PostgreSQL官方推荐使用 timestamptz。
时区处理的关键问题
- 会话时区(session timezone)会影响TIMESTAMP类的读写结果
- 连接池中不同连接的会话时区可能不一致,导致数据混乱
- 跨夏令时写入TIMESTAMP可能引发歧义
最佳实践
- 统一用UTC存储:应用层统一以UTC写入
- 用带时区的类型:PostgreSQL用timestamptz,MySQL视需求选择并统一
- 固定会话时区:如MySQL设置
time_zone = '+00:00' - 展示层再转本地时间:由前端或业务层按用户时区格式化
结语
数据库时间存储的核心是明确“存的是绝对时刻还是字面时间”。选对类型、统一时区,才能避免跨时区数据出错。