Jedną z kluczowych różnic między JSON a JSONB jest format przechowywania danych. JSON zapisuje dane jako tekst, a JSONB — w formie binarnej. To oznacza, że:
- JSON przechowuje dane dokładnie w takiej postaci, w jakiej je podałeś. Na przykład, jeśli wrzucisz stringa
{"title": "PostgreSQL", "tags": ["database", "SQL"]}, zostanie on zapisany dokładnie tak, jak go wysłałeś. - JSONB najpierw parsuje obiekt JSON, usuwa zbędne spacje, sortuje klucze, optymalizuje strukturę i dopiero potem zapisuje ją w formacie binarnym.
Ta optymalizacja sprawia, że JSONB szybciej ogarnia dane, szczególnie przy bardziej złożonych zapytaniach do filtrowania, wyszukiwania i sortowania.
Wydajność operacji odczytu i zapisu
JSON i JSONB mają różne cechy jeśli chodzi o szybkość zapisu i odczytu danych:
- JSON szybciej zapisuje się do bazy, bo nie trzeba parsować danych przed zapisaniem. Ale odczyt i przetwarzanie takich danych jest zwykle wolniejsze, bo PostgreSQL podczas zapytania musi jeszcze raz parsować dane.
- JSONB potrzebuje więcej czasu na zapis, bo przed zapisaniem dane są obrabiane. Ale odczyt, filtrowanie i wyciąganie wartości jest dużo szybsze, więc JSONB jest lepszy do zadań analitycznych albo wyszukiwania.
Przykład dla jasności:
-- Tworzenie tabel z JSON i JSONB
CREATE TABLE json_example (data JSON);
CREATE TABLE jsonb_example (data JSONB);
-- Wstawianie danych
INSERT INTO json_example VALUES ('{"key": "wartość", "tags": ["json", "przykład"]}');
INSERT INTO jsonb_example VALUES ('{"key": "wartość", "tags": ["jsonb", "przykład"]}');
-- Filtrowanie danych
SELECT * FROM json_example WHERE data->'key' = '"wartość"'; -- Wolniej
SELECT * FROM jsonb_example WHERE data->'key' = '"wartość"'; -- Szybciej
Indeksowanie danych
Jedną z największych zalet JSONB jest wsparcie dla indeksowania. PostgreSQL pozwala tworzyć indeksy na kolumnach JSONB, używając typu indeksu GIN. To mocno przyspiesza wyszukiwanie i filtrowanie danych.
Przykład tworzenia indeksu:
-- Indeks na kolumnie JSONB
CREATE INDEX idx_jsonb_tags ON jsonb_example USING gin (data->'tags');
JSON, w przeciwieństwie, nie wspiera indeksowania, co sprawia, że jest mniej wygodny do złożonych operacji wyszukiwania i filtrowania.
Kiedy używać JSON, a kiedy JSONB
JSON najlepiej sprawdza się, gdy:
- Musisz przechowywać dane w oryginalnej postaci, bez zmian.
- Nie planujesz aktywnie wykonywać zapytań do filtrowania, wyszukiwania czy sortowania po danych JSON.
- Dane JSON są głównie przekazywane do innych systemów lub klientów w niezmienionej formie (np. wysyłane do frontendu przez API).
Przykład:
-- Przechowywanie JSON bez analizy
CREATE TABLE api_responses (
id SERIAL PRIMARY KEY,
response JSON
);
-- Wstawianie danych, tak jak przyszły z API
INSERT INTO api_responses (response)
VALUES ('{"status": "sukces", "payload": {"id": 123, "name": "Jan"}}');
JSONB warto użyć, jeśli:
- Planujesz aktywnie filtrować, wyszukiwać, grupować lub sortować dane po wartościach wewnątrz JSON.
- Wydajność dostępu do danych jest ważniejsza niż wydajność zapisu.
- Chcesz używać indeksowania, żeby przyspieszyć operacje na danych JSON.
Przykład:
-- Przechowywanie JSONB do analizy i pracy z obiektami zagnieżdżonymi
CREATE TABLE products (
id SERIAL PRIMARY KEY,
details JSONB
);
-- Wstawianie danych
INSERT INTO products (details)
VALUES ('{"name": "Laptop", "price": 1200, "tags": ["elektronika", "komputery"]}');
-- Szukanie produktów z tagiem "elektronika"
SELECT * FROM products
WHERE details @> '{"tags": ["elektronika"]}';
Więcej o operatorach @> i --> dowiesz się w kolejnych wykładach :P
Przykłady pracy z JSON i JSONB
Stwórzmy dwie tabele: jedną z kolumną JSON, drugą z JSONB:
CREATE TABLE json_table (
id SERIAL PRIMARY KEY,
data JSON
);
CREATE TABLE jsonb_table (
id SERIAL PRIMARY KEY,
data JSONB
);
Wstawianie danych będzie identyczne dla obu tabel:
INSERT INTO json_table (data)
VALUES ('{"key": "wartość", "tags": ["json", "przykład"]}');
INSERT INTO jsonb_table (data)
VALUES ('{"key": "wartość", "tags": ["jsonb", "przykład"]}');
Teraz spróbujmy wyciągnąć dane, gdzie klucz key ma wartość wartość:
-- Dla JSON
SELECT * FROM json_table
WHERE data->>'key' = 'wartość';
-- Dla JSONB
SELECT * FROM jsonb_table
WHERE data->>'key' = 'wartość';
Dla małych ilości danych różnica w wydajności będzie praktycznie niezauważalna. Ale przy pracy z milionami wierszy JSONB pokaże dużo lepsze wyniki, szczególnie jeśli zrobisz indeks:
CREATE INDEX idx_jsonb_key ON jsonb_table USING gin ((data->>'key'));
Praca z obiektami zagnieżdżonymi i tablicami też jest wydajniejsza w JSONB:
-- Wyciąganie wartości z tablicy
SELECT data->'tags'->>0 AS pierwszy_tag
FROM jsonb_table;
Zalety i wady
| Cecha | JSON | JSONB |
|---|---|---|
| Przechowywanie danych | Przechowuje dane w oryginalnym formacie tekstowym | Przechowuje dane w formacie binarnym, sortując klucze |
| Wydajność zapisu | Szybciej, bo zapisuje "jak jest" | Wolniej przez wstępny parsing |
| Wydajność odczytu | Wolniej, bo dane trzeba parsować podczas zapytania | Szybciej, bo dane są już zoptymalizowane do odczytu |
| Indeksowanie | Nieobsługiwane | Obsługiwane (indeksy GIN, BTREE) |
| Filtrowanie | Wolne | Szybkie |
| Wsparcie operacji | Ograniczone | Rozszerzone |
Wybór między JSON a JSONB zależy od charakteru zadania. Jeśli chcesz po prostu przechowywać dane w niezmienionej formie tekstowej, śmiało wybierz JSON. Jeśli jednak planujesz aktywnie pracować na danych w kolumnach, filtrować, wyszukiwać czy grupować — JSONB będzie wydajniejszy i wygodniejszy.
Dla bardziej złożonych aplikacji, gdzie dane JSON to nie tylko "magazyn", ale są aktywnie wykorzystywane w analizie, JSONB stanie się niezastąpionym narzędziem. Więc jeśli się wahasz — wybierz JSONB. Może Twój przyszły "najszybszy query życia" Ci za to podziękuje!
GO TO FULL VERSION