最近在用KingFusion低代码平台开发MES系统的这个项目中使用的是PG数据库。
今天在在存储一个日期+时间格式的数据时报错,于是借此整理下日期时间字段该选择何种数据类型。
对于存储 2026-05-18 11:05:17 这种日期 + 时间 格式的数据,PostgreSQL 官方推荐使用 timestamp without time zone 类型 (通常简称为 timestamp)。
一、最佳选择:timestamp without time zone
1. 基本特性
- 存储内容 :精确到微秒的日期和时间(
YYYY-MM-DD HH:MM:SS.ffffff) - 存储大小:8 字节
- 精度范围:4713 BC 到 294276 AD
- 默认精度 :6 位小数(微秒级),可手动指定精度(如
timestamp(3)表示毫秒级)
2. 表设计示例
CREATE TABLE your_table (
id serial PRIMARY KEY,
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 推荐写法
update_time timestamp
);
3. 插入数据示例
-- 直接使用字符串插入,PG会自动转换
INSERT INTO your_table (create_time) VALUES ('2026-05-18 11:05:17');
-- 也可以使用标准函数
INSERT INTO your_table (create_time) VALUES (NOW());
INSERT INTO your_table (create_time) VALUES (CURRENT_TIMESTAMP);
二、其他相关类型对比
| 类型 | 存储内容 | 适用场景 | 不适用场景 |
|---|---|---|---|
timestamp without time zone |
本地日期 + 时间,无时区信息 | 所有用户在同一时区、只关心本地时间的场景(如国内单区域系统) | 跨时区应用、需要处理不同时区用户的场景 |
timestamp with time zone(简称 timestamptz) |
UTC 时间戳 + 时区偏移 | 跨时区应用、全球用户系统、需要准确记录时间点的场景 | 只需要本地时间、不需要时区转换的场景 |
date |
仅日期(YYYY-MM-DD) |
只需要记录日期、不需要时间的场景(如生日、订单日期) | 需要精确到时分秒的场景 |
time without time zone |
仅时间(HH:MM:SS) |
只需要记录时间、不需要日期的场景(如每日定时任务时间) | 需要完整日期时间的场景 |
varchar/text |
字符串形式的日期时间 | ❌ 绝对不推荐 | 所有需要日期时间计算、排序、索引的场景 |
三、关键注意事项
1. 绝对不要用 varchar 存储日期时间
这是最常见的错误做法,会导致:
- 无法使用 PG 强大的日期时间函数(如
DATE_TRUNC、AGE、EXTRACT) - 排序错误(字符串排序
2026-05-18会排在2026-05-2前面) - 索引失效,查询性能极差
- 数据格式不统一,容易出现脏数据
2. timestamp vs timestamptz 核心区别
- 存储方式 :两者都占用 8 字节,
timestamptz实际存储的是 UTC 时间戳 - 显示方式 :
timestamptz会根据数据库或客户端的时区自动转换显示 - 推荐原则 :
- 国内单区域系统:用
timestamp即可 - 跨时区 / 全球化系统:用
timestamptz,统一存储 UTC 时间
- 国内单区域系统:用
3. 关于 datetime 类型
PostgreSQL 虽然支持 datetime 类型,但这是为了兼容 MySQL 而保留的别名 ,本质上和 timestamp without time zone 完全一样。官方推荐直接使用 timestamp。
四、最佳实践总结
- 存储
2026-05-18 11:05:17这种格式 :使用timestamp without time zone - 需要跨时区处理 :使用
timestamp with time zone - 只需要日期 :使用
date - 设置默认值 :推荐使用
CURRENT_TIMESTAMP自动记录创建时间 - 避免使用 :
varchar、text、datetime(别名)
