只要你在搞数据,基本总会遇到跟时间有关的东西。比如航班表、订单截止时间,或者用户啥时候在网站注册的。这些全都是时间相关的。想要用得顺手,得有合适的工具。PostgreSQL就有专门的数据类型,专门用来存和处理日期时间,特别方便。
当然,你也可以直接把日期当成字符串存,比如"2023-10-12",但这其实是个坑,不是啥好办法。字符串不会比较日期,不知道啥叫“加三天”,更不懂时区。而时间类型的数据就全都懂了,还能做更多事。用它们又简单又靠谱,还快。
DATE类型
DATE类型就是专门用来存日历日期的,不带具体时间。如果你只关心日期,比如生日、某年开始的那天啥的,这就很合适。
举个例子:
-- 用`DATE`类型建个表的例子
CREATE TABLE events (
event_name TEXT,
event_date DATE
);
-- 插入数据
INSERT INTO events (event_name, event_date)
VALUES ('PostgreSQL大会', '2023-12-01'),
('生日', '2023-10-12');
-- 查询
SELECT * FROM events;
结果:
| event_name | event_date |
|---|---|
| PostgreSQL大会 | 2023-12-01 |
| 生日 | 2023-10-12 |
TIME类型
TIME类型只存时间,比如小时、分钟、秒。特别适合搞排班表,比如公交车时刻表、商店营业时间啥的。
举个例子:
-- 用`TIME`类型建表
CREATE TABLE schedules (
schedule_name TEXT,
start_time TIME,
end_time TIME
);
-- 插入数据
INSERT INTO schedules (schedule_name, start_time, end_time)
VALUES ('上班时间', '09:00:00', '18:00:00'),
('午休', '13:00:00', '14:00:00');
-- 查询
SELECT schedule_name, start_time, end_time FROM schedules;
结果:
| schedule_name | start_time | end_time |
|---|---|---|
| 上班时间 | 09:00:00 | 18:00:00 |
| 午休 | 13:00:00 | 14:00:00 |
TIMESTAMP类型
TIMESTAMP类型把日期和时间合成一个值。不过它不带时区。如果你的数据会被不同时区的用户用,可能会有点乱。
举个例子:
-- 用`TIMESTAMP`类型建表
CREATE TABLE documents (
document_id SERIAL PRIMARY KEY,
created_at TIMESTAMP
);
-- 插入数据
INSERT INTO documents (created_at)
VALUES ('2023-10-12 15:30:00'),
('2023-12-01 08:45:15');
-- 查询
SELECT document_id, created_at FROM documents;
结果:
| document_id | created_at |
|---|---|
| 1 | 2023-10-12 15:30:00 |
| 2 | 2023-12-01 08:45:15 |
TIMESTAMPTZ类型
TIMESTAMPTZ类型(TZ就是“时区”的意思)跟TIMESTAMP差不多,但它还会存时区信息。要是你的应用有国际用户,这个就很重要了。
举个例子:
-- 用`TIMESTAMPTZ`类型建表
CREATE TABLE meetings (
meeting_id SERIAL PRIMARY KEY,
meeting_time TIMESTAMPTZ
);
-- 插入数据(PostgreSQL会保存当前时区)
INSERT INTO meetings (meeting_time)
VALUES ('2023-10-12 15:30:00+03'),
('2023-12-01 08:45:15-05');
-- 查询
SELECT meeting_id, meeting_time FROM meetings;
结果:
| meeting_id | meeting_time |
|---|---|
| 1 | 2023-10-12 15:30:00+03:00 |
| 2 | 2023-12-01 08:45:15-05:00 |
注意,PostgreSQL会自动把时间转成服务器的时区。
用专门数据类型的好处
数据靠谱。嵌入DATE和TIMESTAMP这种类型,可以防止你存错数据。比如你不能存个"2023-02-30"这种根本不存在的日期。
用起来方便。你可以直接比较日期、做减法、拿到当前日期,甚至还能四舍五入(后面会讲到)。
性能好。时间类型的数据比字符串占的内存和索引空间都小,查询也更快。
例子:用所有类型建个表
我们来建个更复杂的表,用来存活动日程。这里会用到DATE、TIME、TIMESTAMP和TIMESTAMPTZ。
CREATE TABLE event_schedule (
event_id SERIAL PRIMARY KEY,
event_name TEXT NOT NULL,
event_date DATE NOT NULL,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
full_start TIMESTAMP NOT NULL,
full_start_with_zone TIMESTAMPTZ NOT NULL
);
-- 插入数据
INSERT INTO event_schedule (
event_name, event_date, start_time, end_time, full_start, full_start_with_zone
)
VALUES
('早间见面会', '2023-11-10', '10:00:00', '11:30:00', '2023-11-10 10:00:00', '2023-11-10 10:00:00+03'),
('晚间workshop', '2023-11-11', '18:00:00', '20:00:00', '2023-11-11 18:00:00', '2023-11-11 18:00:00+03');
-- 查询
SELECT * FROM event_schedule;
结果:
| event_id | event_name | event_date | start_time | end_time | full_start | fullstartwith_zone |
|---|---|---|---|---|---|---|
| 1 | 早间见面会 | 2023-11-10 | 10:00:00 | 11:30:00 | 2023-11-10 10:00:00 | 2023-11-10 10:00:00+03:00 |
| 2 | 晚间workshop | 2023-11-11 | 18:00:00 | 20:00:00 | 2023-11-11 18:00:00 | 2023-11-11 18:00:00+03:00 |
这就是一个真实的日程管理数据库例子。你可以看到,不同的时间数据格式可以互补,具体用哪个看你需求。
希望你现在记得怎么在PostgreSQL里用DATE、TIME、TIMESTAMP和TIMESTAMPTZ了。接下来的课我们会更深入聊聊时间函数,学会怎么用SQL查询提取、格式化和管理时间数据。
GO TO FULL VERSION