Una delle differenze chiave tra JSON e JSONB sta nel formato di memorizzazione dei dati. JSON salva i dati come testo, mentre JSONB li salva in forma binaria. Questo significa che:
- JSON salva i dati esattamente come li hai passati. Per esempio, se inserisci la stringa
{"title": "PostgreSQL", "tags": ["database", "SQL"]}, verrà salvata così com'è. - JSONB prima fa il parsing dell'oggetto JSON, elimina gli spazi inutili, ordina le chiavi, ottimizza la struttura e solo dopo la salva in formato binario.
Questa ottimizzazione permette a JSONB di lavorare più velocemente con i dati, soprattutto quando fai query complesse di filtro, ricerca e ordinamento.
Performance di lettura e scrittura
JSON e JSONB hanno caratteristiche diverse per quanto riguarda la velocità di lettura e scrittura dei dati:
- JSON viene scritto più velocemente nel database, perché non c'è bisogno di fare il parsing prima di salvarlo. Però la lettura e l'elaborazione di questi dati di solito è più lenta, perché PostgreSQL deve fare il parsing ogni volta che esegue una query.
- JSONB richiede più tempo in scrittura, perché i dati vengono processati prima di essere salvati. Però la lettura, il filtraggio e l'estrazione dei valori sono molto più veloci, il che rende JSONB la scelta migliore per analisi o ricerche.
Ecco un esempio per chiarire:
-- Creazione di tabelle con JSON e JSONB
CREATE TABLE json_example (data JSON);
CREATE TABLE jsonb_example (data JSONB);
-- Inserimento dati
INSERT INTO json_example VALUES ('{"key": "valore", "tags": ["json", "esempio"]}');
INSERT INTO jsonb_example VALUES ('{"key": "valore", "tags": ["jsonb", "esempio"]}');
-- Filtro dei dati
SELECT * FROM json_example WHERE data->'key' = '"valore"'; -- Più lento
SELECT * FROM jsonb_example WHERE data->'key' = '"valore"'; -- Più veloce
Indicizzazione dei dati
Uno dei maggiori vantaggi di JSONB è il supporto per l'indicizzazione. PostgreSQL permette di creare indici sulle colonne JSONB usando il tipo di indice GIN. Questo velocizza tantissimo la ricerca e il filtraggio dei dati.
Esempio di creazione di un indice:
-- Indice su una colonna JSONB
CREATE INDEX idx_jsonb_tags ON jsonb_example USING gin (data->'tags');
JSON, invece, non supporta l'indicizzazione, il che lo rende meno adatto per operazioni di ricerca e filtro complesse.
Quando usare JSON e quando JSONB
JSON è la scelta migliore quando:
- Hai bisogno di salvare i dati esattamente come sono, senza modifiche.
- Non prevedi di fare query attive per filtrare, cercare o ordinare i dati JSON.
- I dati JSON vengono usati principalmente per essere inviati ad altri sistemi o client senza modifiche (ad esempio, per mandarli al frontend tramite API).
Esempio:
-- Salvataggio di JSON senza analisi
CREATE TABLE api_responses (
id SERIAL PRIMARY KEY,
response JSON
);
-- Inserimento dei dati così come arrivano dall'API
INSERT INTO api_responses (response)
VALUES ('{"status": "successo", "payload": {"id": 123, "nome": "Giovanni"}}');
JSONB conviene usarlo se:
- Hai intenzione di filtrare, cercare, raggruppare o ordinare attivamente i dati in base ai valori dentro il JSON.
- La performance di accesso ai dati è più importante della velocità di scrittura.
- Vuoi usare l'indicizzazione per velocizzare le operazioni sui dati JSON.
Esempio:
-- Salvataggio di JSONB per analisi e lavoro con oggetti annidati
CREATE TABLE products (
id SERIAL PRIMARY KEY,
details JSONB
);
-- Inserimento dati
INSERT INTO products (details)
VALUES ('{"nome": "Laptop", "prezzo": 1200, "tags": ["elettronica", "computer"]}');
-- Ricerca di prodotti con il tag "elettronica"
SELECT * FROM products
WHERE details @> '{"tags": ["elettronica"]}';
Scoprirai di più sugli operatori @> e --> nelle prossime lezioni :P
Esempi di lavoro con JSON e JSONB
Creiamo due tabelle: una con una colonna JSON, l'altra con una colonna JSONB:
CREATE TABLE json_table (
id SERIAL PRIMARY KEY,
data JSON
);
CREATE TABLE jsonb_table (
id SERIAL PRIMARY KEY,
data JSONB
);
L'inserimento dei dati sarà uguale per entrambe le tabelle:
INSERT INTO json_table (data)
VALUES ('{"key": "valore", "tags": ["json", "esempio"]}');
INSERT INTO jsonb_table (data)
VALUES ('{"key": "valore", "tags": ["jsonb", "esempio"]}');
Ora proviamo a estrarre i dati dove la chiave key ha valore valore:
-- Per JSON
SELECT * FROM json_table
WHERE data->>'key' = 'valore';
-- Per JSONB
SELECT * FROM jsonb_table
WHERE data->>'key' = 'valore';
Per piccoli volumi di dati la differenza di performance sarà praticamente invisibile. Ma se lavori con milioni di righe, JSONB darà risultati molto migliori, soprattutto se crei un indice:
CREATE INDEX idx_jsonb_key ON jsonb_table USING gin ((data->>'key'));
Lavorare con oggetti annidati e array è anche più efficiente in JSONB:
-- Estrazione di un valore da un array
SELECT data->'tags'->>0 AS primo_tag
FROM jsonb_table;
Vantaggi e svantaggi
| Caratteristica | JSON | JSONB |
|---|---|---|
| Memorizzazione dati | Salva i dati in formato testo originale | Salva i dati in formato binario, ordinando le chiavi |
| Performance di scrittura | Più veloce, perché salva "così com'è" | Più lenta per via del parsing preventivo |
| Performance di lettura | Più lenta, perché i dati vanno parsati al momento della query | Più veloce, perché i dati sono già ottimizzati per la lettura |
| Indicizzazione | Non supportata | Supportata (indici GIN, BTREE) |
| Filtraggio | Lento | Veloce |
| Supporto operazioni | Limitato | Esteso |
La scelta tra JSON e JSONB dipende dal tipo di progetto. Se ti serve solo salvare i dati in formato testo senza modificarli, vai tranquillo con JSON. Se invece pensi di lavorare attivamente con i dati nelle colonne, fare filtri, ricerche o raggruppamenti, JSONB sarà più performante e comodo.
Per applicazioni complesse, dove i dati JSON non sono solo "storage" ma vengono usati attivamente per analisi, JSONB diventa uno strumento indispensabile. Quindi, se hai dubbi — scegli JSONB. Magari la tua futura "query più veloce della vita" ti ringrazierà!
GO TO FULL VERSION