Khi làm việc với dữ liệu, gần như lúc nào cũng sẽ gặp cái gì đó liên quan đến thời gian. Nghĩ thử xem: lịch bay, deadline đơn hàng hay ngày user đăng ký trên web. Tất cả đều dính tới thời gian hết. Và để xử lý ngon lành, phải có công cụ phù hợp. Trong PostgreSQL có mấy kiểu dữ liệu chuyên biệt, cực kỳ hợp để lưu trữ và xử lý ngày tháng, thời gian.
Đúng là có thể lưu ngày tháng kiểu string như "2023-10-12", nhưng như vậy là tự đào hố cho mình thôi. String thì không biết so sánh ngày tháng, không biết "cộng thêm ba ngày" là gì, càng không biết múi giờ là cái gì luôn. Còn mấy kiểu dữ liệu thời gian thì biết hết, thậm chí còn hơn thế nữa. Dùng chúng vừa dễ, vừa chuẩn, vừa nhanh.
Kiểu DATE
Kiểu DATE dùng để lưu mỗi ngày tháng thôi, không có giờ phút gì cả. Rất tiện nếu bạn chỉ cần làm việc với ngày tháng như ngày sinh, ngày bắt đầu năm mới, v.v.
Ví dụ sử dụng:
-- Ví dụ tạo bảng với kiểu `DATE`
CREATE TABLE events (
event_name TEXT,
event_date DATE
);
-- Thêm dữ liệu
INSERT INTO events (event_name, event_date)
VALUES ('Hoi nghi PostgreSQL', '2023-12-01'),
('Sinh nhat', '2023-10-12');
-- Truy vấn dữ liệu
SELECT * FROM events;
Kết quả:
| event_name | event_date |
|---|---|
| Hoi nghi PostgreSQL | 2023-12-01 |
| Sinh nhat | 2023-10-12 |
Kiểu TIME
Kiểu TIME chỉ lưu THỜI GIAN thôi, tức là giờ, phút, giây. Rất hợp cho mấy bài toán kiểu lịch trình xe bus, giờ mở cửa, giờ nghỉ trưa, v.v.
Ví dụ:
-- Ví dụ tạo bảng với `TIME`
CREATE TABLE schedules (
schedule_name TEXT,
start_time TIME,
end_time TIME
);
-- Thêm dữ liệu
INSERT INTO schedules (schedule_name, start_time, end_time)
VALUES ('Thoi gian lam viec', '09:00:00', '18:00:00'),
('Nghi trua', '13:00:00', '14:00:00');
-- Truy vấn dữ liệu
SELECT schedule_name, start_time, end_time FROM schedules;
Kết quả:
| schedule_name | start_time | end_time |
|---|---|---|
| Thoi gian lam viec | 09:00:00 | 18:00:00 |
| Nghi trua | 13:00:00 | 14:00:00 |
Kiểu TIMESTAMP
Kiểu TIMESTAMP kết hợp cả ngày tháng lẫn thời gian trong một giá trị. Nhưng nó KHÔNG lưu thông tin múi giờ đâu nhé. Nếu user ở nhiều múi giờ khác nhau thì dễ bị rối lắm.
Ví dụ:
-- Ví dụ tạo bảng với `TIMESTAMP`
CREATE TABLE documents (
document_id SERIAL PRIMARY KEY,
created_at TIMESTAMP
);
-- Thêm dữ liệu
INSERT INTO documents (created_at)
VALUES ('2023-10-12 15:30:00'),
('2023-12-01 08:45:15');
-- Truy vấn dữ liệu
SELECT document_id, created_at FROM documents;
Kết quả:
| document_id | created_at |
|---|---|
| 1 | 2023-10-12 15:30:00 |
| 2 | 2023-12-01 08:45:15 |
Kiểu TIMESTAMPTZ
Kiểu TIMESTAMPTZ (chữ TZ là "múi giờ") giống TIMESTAMP nhưng còn lưu cả thông tin múi giờ nữa. Cực kỳ cần thiết cho app có user quốc tế.
Ví dụ:
-- Ví dụ tạo bảng với `TIMESTAMPTZ`
CREATE TABLE meetings (
meeting_id SERIAL PRIMARY KEY,
meeting_time TIMESTAMPTZ
);
-- Thêm dữ liệu (PostgreSQL sẽ lưu múi giờ hiện tại)
INSERT INTO meetings (meeting_time)
VALUES ('2023-10-12 15:30:00+03'),
('2023-12-01 08:45:15-05');
-- Truy vấn dữ liệu
SELECT meeting_id, meeting_time FROM meetings;
Kết quả:
| meeting_id | meeting_time |
|---|---|
| 1 | 2023-10-12 15:30:00+03:00 |
| 2 | 2023-12-01 08:45:15-05:00 |
Lưu ý là PostgreSQL sẽ tự động chuyển thời gian về múi giờ của server nhé.
Ưu điểm khi dùng kiểu dữ liệu chuyên biệt
Dữ liệu chuẩn xác. Các kiểu như DATE và TIMESTAMP sẽ không cho nhập dữ liệu sai. Ví dụ, không thể lưu ngày không tồn tại như "2023-02-30".
Dễ thao tác. Có thể so sánh ngày tháng, trừ ngày, lấy ngày hiện tại, thậm chí làm tròn giá trị (phần này sẽ nói sau).
Tối ưu hiệu năng. Kiểu dữ liệu thời gian chiếm ít bộ nhớ và index hơn string, nên query chạy nhanh hơn.
Ví dụ: tạo bảng dùng tất cả các kiểu
Làm thử bảng phức tạp hơn để lưu lịch sự kiện nhé. Sẽ dùng luôn cả DATE, TIME, TIMESTAMP và 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
);
-- Thêm dữ liệu
INSERT INTO event_schedule (
event_name, event_date, start_time, end_time, full_start, full_start_with_zone
)
VALUES
('Buoi meetup sang', '2023-11-10', '10:00:00', '11:30:00', '2023-11-10 10:00:00', '2023-11-10 10:00:00+03'),
('Workshop toi', '2023-11-11', '18:00:00', '20:00:00', '2023-11-11 18:00:00', '2023-11-11 18:00:00+03');
-- Kiểm tra dữ liệu
SELECT * FROM event_schedule;
Kết quả:
| event_id | event_name | event_date | start_time | end_time | full_start | fullstartwith_zone |
|---|---|---|---|---|---|---|
| 1 | Buoi meetup sang | 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 toi | 2023-11-11 | 18:00:00 | 20:00:00 | 2023-11-11 18:00:00 | 2023-11-11 18:00:00+03:00 |
Đây là ví dụ thực tế về database quản lý lịch trình. Thấy rõ là mỗi kiểu dữ liệu thời gian đều có vai trò riêng, tuỳ vào bài toán mà dùng cho hợp lý.
Hy vọng bạn đã nhớ cách dùng DATE, TIME, TIMESTAMP và TIMESTAMPTZ trong PostgreSQL rồi nhé. Ở các bài sau sẽ đào sâu hơn về hàm thời gian, cách lấy, format và xử lý dữ liệu thời gian bằng SQL query.
GO TO FULL VERSION