Einer der wichtigsten Unterschiede zwischen JSON und JSONB ist das Speicherformat der Daten. JSON speichert Daten als Text, während JSONB sie binär ablegt. Das bedeutet:
- JSON speichert die Daten genau so, wie du sie übergibst. Zum Beispiel, wenn du den String
{"title": "PostgreSQL", "tags": ["database", "SQL"]}einfügst, wird er exakt so gespeichert. - JSONB parst zuerst das JSON-Objekt, entfernt unnötige Leerzeichen, sortiert die Keys, optimiert die Struktur und speichert sie dann erst im Binärformat.
Durch diese Optimierung kann JSONB schneller mit Daten arbeiten, besonders bei komplexen Filter-, Such- und Sortierabfragen.
Performance bei Lese- und Schreiboperationen
JSON und JSONB haben unterschiedliche Eigenschaften, was die Geschwindigkeit beim Lesen und Schreiben von Daten angeht:
- JSON wird schneller in die Datenbank geschrieben, weil die Daten nicht vor dem Speichern geparst werden müssen. Das Lesen und Verarbeiten solcher Daten ist aber meist langsamer, weil PostgreSQL die Daten bei jeder Abfrage neu parsen muss.
- JSONB braucht mehr Zeit beim Schreiben, weil die Daten vor dem Speichern verarbeitet werden. Das Lesen, Filtern und Extrahieren von Werten geht dafür viel schneller, was JSONB für analytische oder Suchaufgaben bevorzugt macht.
Ein Beispiel zur Veranschaulichung:
-- Tabellen mit JSON und JSONB erstellen
CREATE TABLE json_example (data JSON);
CREATE TABLE jsonb_example (data JSONB);
-- Daten einfügen
INSERT INTO json_example VALUES ('{"key": "wert", "tags": ["json", "beispiel"]}');
INSERT INTO jsonb_example VALUES ('{"key": "wert", "tags": ["jsonb", "beispiel"]}');
-- Daten filtern
SELECT * FROM json_example WHERE data->'key' = '"wert"'; -- Langsamer
SELECT * FROM jsonb_example WHERE data->'key' = '"wert"'; -- Schneller
Datenindizierung
Einer der größten Vorteile von JSONB ist die Unterstützung von Indizes. PostgreSQL erlaubt es, Indizes für JSONB-Spalten mit dem Index-Typ GIN zu erstellen. Das beschleunigt Suche und Filterung enorm.
Beispiel für das Erstellen eines Indexes:
-- Index auf einer JSONB-Spalte
CREATE INDEX idx_jsonb_tags ON jsonb_example USING gin (data->'tags');
JSON hingegen unterstützt keine Indizierung, was es für komplexe Such- und Filteroperationen weniger geeignet macht.
Wann solltest du JSON und wann JSONB verwenden?
JSON eignet sich am besten, wenn:
- Du Daten im Originalzustand speichern willst, ohne Änderungen.
- Du nicht vorhast, viele Filter-, Such- oder Sortierabfragen auf den JSON-Daten auszuführen.
- Die JSON-Daten hauptsächlich dazu dienen, sie unverändert an andere Systeme oder Clients weiterzugeben (z.B. an das Frontend via API).
Beispiel:
-- JSON speichern ohne Analyse
CREATE TABLE api_responses (
id SERIAL PRIMARY KEY,
response JSON
);
-- Daten einfügen, wie sie von der API kamen
INSERT INTO api_responses (response)
VALUES ('{"status": "erfolg", "payload": {"id": 123, "name": "Johann"}}');
JSONB solltest du verwenden, wenn:
- Du planst, aktiv nach Werten im JSON zu filtern, zu suchen, zu gruppieren oder zu sortieren.
- Die Performance beim Datenzugriff wichtiger ist als die Schreibgeschwindigkeit.
- Du Indizierung nutzen willst, um Operationen mit JSON-Daten zu beschleunigen.
Beispiel:
-- JSONB speichern für Analyse und Arbeit mit verschachtelten Objekten
CREATE TABLE products (
id SERIAL PRIMARY KEY,
details JSONB
);
-- Daten einfügen
INSERT INTO products (details)
VALUES ('{"name": "Laptop", "price": 1200, "tags": ["elektronik", "computer"]}');
-- Produkte mit dem Tag "elektronik" suchen
SELECT * FROM products
WHERE details @> '{"tags": ["elektronik"]}';
Mehr über die Operatoren @> und --> erfährst du in den nächsten Lektionen :P
Beispiele für die Arbeit mit JSON und JSONB
Wir erstellen zwei Tabellen: eine mit einer JSON-Spalte, die andere mit einer JSONB-Spalte:
CREATE TABLE json_table (
id SERIAL PRIMARY KEY,
data JSON
);
CREATE TABLE jsonb_table (
id SERIAL PRIMARY KEY,
data JSONB
);
Das Einfügen der Daten ist für beide Tabellen gleich:
INSERT INTO json_table (data)
VALUES ('{"key": "wert", "tags": ["json", "beispiel"]}');
INSERT INTO jsonb_table (data)
VALUES ('{"key": "wert", "tags": ["jsonb", "beispiel"]}');
Jetzt versuchen wir, Daten zu extrahieren, bei denen der Key key den Wert wert hat:
-- Für JSON
SELECT * FROM json_table
WHERE data->>'key' = 'wert';
-- Für JSONB
SELECT * FROM jsonb_table
WHERE data->>'key' = 'wert';
Bei kleinen Datenmengen ist der Performance-Unterschied kaum spürbar. Aber wenn du mit Millionen von Zeilen arbeitest, zeigt JSONB deutlich bessere Ergebnisse, besonders wenn du einen Index erstellst:
CREATE INDEX idx_jsonb_key ON jsonb_table USING gin ((data->>'key'));
Auch die Arbeit mit verschachtelten Objekten und Arrays ist in JSONB effizienter:
-- Wert aus Array extrahieren
SELECT data->'tags'->>0 AS erster_tag
FROM jsonb_table;
Vorteile und Nachteile
| Eigenschaft | JSON | JSONB |
|---|---|---|
| Datenspeicherung | Speichert Daten im ursprünglichen Textformat | Speichert Daten im Binärformat, sortiert die Keys |
| Schreibperformance | Schneller, weil "wie sie sind" gespeichert wird | Langsamer wegen vorherigem Parsen |
| Leseperformance | Langsamer, weil die Daten beim Abfragen geparst werden müssen | Schneller, weil die Daten schon fürs Lesen optimiert sind |
| Indizierung | Nicht unterstützt | Unterstützt (GIN, BTREE Indizes) |
| Filterung | Langsam | Schnell |
| Unterstützung von Operationen | Begrenzt | Erweitert |
Die Wahl zwischen JSON und JSONB hängt von deiner Aufgabe ab. Wenn du Daten einfach nur im unveränderten Textformat speichern willst, nimm JSON. Wenn du aber aktiv mit den Daten in den Spalten arbeiten, filtern, suchen oder gruppieren willst, ist JSONB die performantere und bequemere Wahl.
Für komplexe Anwendungen, in denen JSON-Daten nicht nur als "Ablage" dienen, sondern auch aktiv in der Analyse genutzt werden, ist JSONB ein unverzichtbares Tool. Also, wenn du unsicher bist – nimm JSONB. Vielleicht bedankt sich dein zukünftiges "schnellstes Query deines Lebens" bei dir dafür!
GO TO FULL VERSION