Kiedy zaczynasz pracować z danymi, prawie zawsze pojawia się coś związanego z czasem. Pomyśl o rozkładach lotów, deadline'ach zamówień albo dacie, kiedy użytkownik zarejestrował się na stronie. To wszystko — kwestia czasu. I żeby wygodnie z tym działać, potrzebujesz odpowiednich narzędzi. W PostgreSQL są specjalne typy danych, które świetnie ogarniają przechowywanie i obsługę dat oraz czasu.
Jasne, możesz zapisać datę jako zwykły string, np. "2023-10-12", ale to raczej pułapka niż rozwiązanie. Stringi nie potrafią porównywać dat, nie wiedzą co to „plus trzy dni” i totalnie nie ogarniają stref czasowych. A typy czasowe — ogarniają to wszystko i jeszcze więcej. Z nimi jest prościej, pewniej i szybciej.
Typ DATE
Typ DATE służy do przechowywania tylko daty kalendarzowej, bez konkretnej godziny. To wygodne, jeśli chcesz pracować z datami jako niezależnymi bytami, np. datą urodzenia, początkiem roku i tak dalej.
Przykłady użycia:
-- Przykład tworzenia tabeli z typem `DATE`
CREATE TABLE events (
event_name TEXT,
event_date DATE
);
-- Wstawianie danych
INSERT INTO events (event_name, event_date)
VALUES ('Konferencja PostgreSQL', '2023-12-01'),
('Urodziny', '2023-10-12');
-- Zapytanie SELECT
SELECT * FROM events;
Wynik:
| event_name | event_date |
|---|---|
| Konferencja PostgreSQL | 2023-12-01 |
| Urodziny | 2023-10-12 |
Typ TIME
Typ TIME przechowuje TYLKO czas, czyli godziny, minuty i sekundy. Jest idealny do rzeczy związanych z rozkładami, np. rozkład autobusów albo godziny otwarcia sklepów.
Przykłady:
-- Przykład tworzenia tabeli z `TIME`
CREATE TABLE schedules (
schedule_name TEXT,
start_time TIME,
end_time TIME
);
-- Wstawianie danych
INSERT INTO schedules (schedule_name, start_time, end_time)
VALUES ('Godziny pracy', '09:00:00', '18:00:00'),
('Przerwa obiadowa', '13:00:00', '14:00:00');
-- Zapytanie SELECT
SELECT schedule_name, start_time, end_time FROM schedules;
Wynik:
| schedule_name | start_time | end_time |
|---|---|---|
| Godziny pracy | 09:00:00 | 18:00:00 |
| Przerwa obiadowa | 13:00:00 | 14:00:00 |
Typ TIMESTAMP
Typ TIMESTAMP łączy datę kalendarzową i czas w jednej wartości. Ale NIE uwzględnia stref czasowych. To może wprowadzić zamieszanie, jeśli dane będą używane przez ludzi z różnych stref czasowych.
Przykłady:
-- Przykład tworzenia tabeli z `TIMESTAMP`
CREATE TABLE documents (
document_id SERIAL PRIMARY KEY,
created_at TIMESTAMP
);
-- Wstawianie danych
INSERT INTO documents (created_at)
VALUES ('2023-10-12 15:30:00'),
('2023-12-01 08:45:15');
-- Zapytanie SELECT
SELECT document_id, created_at FROM documents;
Wynik:
| document_id | created_at |
|---|---|
| 1 | 2023-10-12 15:30:00 |
| 2 | 2023-12-01 08:45:15 |
Typ TIMESTAMPTZ
Typ TIMESTAMPTZ (gdzie TZ znaczy "strefa czasowa") jest podobny do TIMESTAMP, ale dodatkowo przechowuje info o strefie czasowej. To czyni go niezastąpionym w aplikacjach, które mają użytkowników z różnych krajów.
Przykłady:
-- Przykład tworzenia tabeli z `TIMESTAMPTZ`
CREATE TABLE meetings (
meeting_id SERIAL PRIMARY KEY,
meeting_time TIMESTAMPTZ
);
-- Wstawianie danych (PostgreSQL zapisuje aktualną strefę czasową)
INSERT INTO meetings (meeting_time)
VALUES ('2023-10-12 15:30:00+03'),
('2023-12-01 08:45:15-05');
-- Zapytanie SELECT
SELECT meeting_id, meeting_time FROM meetings;
Wynik:
| meeting_id | meeting_time |
|---|---|
| 1 | 2023-10-12 15:30:00+03:00 |
| 2 | 2023-12-01 08:45:15-05:00 |
Pamiętaj, że PostgreSQL automatycznie konwertuje czas do strefy czasowej serwera.
Zalety używania specjalnych typów danych
Poprawność danych. Typy takie jak DATE i TIMESTAMP nie pozwalają na wpisanie złych danych. Na przykład nie da się zapisać nieistniejącej daty, jak "2023-02-30".
Wygoda pracy. Możesz porównywać daty, odejmować je od siebie, pobierać aktualną datę, a nawet zaokrąglać wartości (o tym pogadamy później).
Wydajność. Typy czasowe zajmują mniej miejsca w pamięci i indeksach niż stringi, więc zapytania działają szybciej.
Przykład: tworzenie tabeli z użyciem wszystkich typów
Stwórzmy bardziej rozbudowaną tabelę do przechowywania harmonogramu wydarzeń. Użyjemy kilku typów naraz: DATE, TIME, TIMESTAMP i 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
);
-- Wstawiamy dane
INSERT INTO event_schedule (
event_name, event_date, start_time, end_time, full_start, full_start_with_zone
)
VALUES
('Poranny meetup', '2023-11-10', '10:00:00', '11:30:00', '2023-11-10 10:00:00', '2023-11-10 10:00:00+03'),
('Wieczorny warsztat', '2023-11-11', '18:00:00', '20:00:00', '2023-11-11 18:00:00', '2023-11-11 18:00:00+03');
-- Sprawdzamy dane
SELECT * FROM event_schedule;
Wynik:
| event_id | event_name | event_date | start_time | end_time | full_start | fullstartwith_zone |
|---|---|---|---|---|---|---|
| 1 | Poranny meetup | 2023-11-10 | 10:00:00 | 11:30:00 | 2023-11-10 10:00:00 | 2023-11-10 10:00:00+03:00 |
| 2 | Wieczorny warsztat | 2023-11-11 | 18:00:00 | 20:00:00 | 2023-11-11 18:00:00 | 2023-11-11 18:00:00+03:00 |
To przykład realnej bazy do zarządzania harmonogramami. Widzisz, jak różne formaty danych czasowych się uzupełniają, w zależności od zadania.
Mam nadzieję, że przypomniałeś sobie, jak używać typów DATE, TIME, TIMESTAMP i TIMESTAMPTZ w PostgreSQL. W kolejnych lekcjach zagłębimy się w funkcje czasowe i nauczymy się wyciągać, formatować i ogarniać dane czasowe za pomocą zapytań SQL.
GO TO FULL VERSION