In PostgreSQL tanti sviluppatori si chiedono: quale struttura dati usare per salvare le informazioni? Meglio usare gli array (ARRAY) per strutture dati semplici? O colonne di testo (TEXT) per le stringhe? O magari HSTORE per salvare coppie "chiave-valore"? E ovviamente, la domanda: ma quando conviene davvero usare JSON o JSONB?
Per aiutarti a capirci qualcosa, vediamo i pro e i contro di ogni approccio, con esempi pratici di utilizzo.
Quando usare gli array (ARRAY) e quando JSONB?
Gli array (ARRAY) sono perfetti per dati che sono insiemi omogenei di valori. Per esempio, se hai una lista di voti degli studenti o tag per un record, gli array sono la scelta giusta.
Esempio di array:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT,
grades INTEGER[] -- array di voti
);
INSERT INTO students (name, grades)
VALUES ('Alice', ARRAY[90, 85, 88]),
('Bob', ARRAY[70, 75, 78]);
Dall'altra parte, JSONB è adatto per strutture più complesse e annidate. Se vuoi salvare dati extra per ogni record, tipo una descrizione per ogni voto, JSONB è quello che fa per te.
Esempio di JSONB:
CREATE TABLE students_json (
id SERIAL PRIMARY KEY,
name TEXT,
grades JSONB -- oggetto con info sui voti
);
INSERT INTO students_json (name, grades)
VALUES ('Alice', '{"Matematica": 90, "Scienze": 85, "Inglese": 88}'),
('Bob', '{"Matematica": 70, "Scienze": 75, "Inglese": 78}');
Differenze principali
| Criterio | Array (ARRAY) |
JSONB |
|---|---|---|
| Struttura | Dati omogenei di un solo tipo | Strutture dati complesse e annidate |
| Accesso ai dati | Per indice: grades[1] |
Per chiave: grades->'Matematica' |
| Supporto indici | Solo GIN o BTREE per l'intero array |
Indici GIN e BTREE comodi sulle chiavi |
| Quando usare | Liste semplici di dati (tag, voti, identificatori) | Oggetti complessi con chiavi e valori |
Esempi di conversione tra array e JSONB
Vediamo come convertire i dati tra array e JSONB:
Array → JSONB
SELECT to_jsonb(grades) AS grades_jsonb
FROM students;
-- Risultato:
-- [{"90","85","88"}]
JSONB → Array
SELECT array_agg(value::INTEGER) AS grades_array
FROM jsonb_array_elements_text('["90", "85", "88"]');
-- Risultato:
-- {90,85,88}
Confronto tra JSONB e dati di testo (TEXT)
Le colonne di testo sono ideali se ti serve solo salvare stringhe di testo o piccoli dati non strutturati. Se il tuo obiettivo è cercare per corrispondenza di stringhe, tipo nel nome di un prodotto o nella descrizione, TEXT è la scelta giusta.
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
description TEXT
);
INSERT INTO books (title, description)
VALUES ('SQL Base', 'Una introduzione concisa a SQL'),
('PostgreSQL Avanzato', 'Una guida approfondita alle performance di PostgreSQL');
Quando conviene usare JSONB?
Se la tua stringa diventa una info con struttura annidata (tipo una descrizione con categoria annidata e lista di tag), meglio scegliere JSONB.
CREATE TABLE books_json (
id SERIAL PRIMARY KEY,
info JSONB
);
INSERT INTO books_json (info)
VALUES ('{"title": "SQL Base", "tags": ["principiante", "database"]}'),
('{"title": "PostgreSQL Avanzato", "tags": ["performance", "ottimizzazione"]}');
Differenze principali
| Criterio | Testo (TEXT) |
JSONB |
|---|---|---|
| Struttura | Dati non strutturati | Dati strutturati e annidati |
| Ricerca | Ricerca full-text | Ricerca per chiavi, valori, struttura annidata |
| Modifica dati | Solo sostituzione completa | Modifica di singole chiavi |
| Quando usare | Semplici stringhe di testo | Dati complessi in formato chiave-valore |
Confronto tra JSONB e HSTORE
HSTORE è il fratello maggiore di JSONB che permette di salvare coppie "chiave-valore". Per esempio, se la tua struttura dati è semplice (non serve annidamento o array), HSTORE è più leggero e veloce.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
attributes HSTORE
);
INSERT INTO products (attributes)
VALUES ('"colore"=>"rosso", "taglia"=>"M"'),
('"colore"=>"blu", "taglia"=>"L"');
Perché JSONB ha sostituito HSTORE?
Anche se HSTORE è comodo per le coppie "chiave-valore", non supporta annidamento e array, quindi JSONB è molto più versatile. Se hai bisogno di qualcosa di più dei semplici oggetti, JSONB è il passo naturale successivo.
Differenze principali
| Criterio | HSTORE | JSONB |
|---|---|---|
| Struttura | Coppie "chiave-valore", senza annidamento | Strutture annidate complete |
| Supporto array | No | Sì |
| Ricerca | Solo per chiave | Per chiavi, valori, struttura annidata |
| Quando usare | Semplici chiave-valore | Strutture dati complesse |
Come scegliere il tipo di dato giusto?
Se hai:
- Struttura semplice — liste o dati omogenei, usa array (
ARRAY). - Semplici stringhe o descrizioni, usa colonne di testo (
TEXT). - Coppie "chiave-valore" senza annidamento, scegli
HSTORE. - Oggetti annidati e array, struttura dati complessa — ti serve JSONB.
Esempi di conversione tra formati
TEXT → JSONB
SELECT to_jsonb('Esempio di testo semplice') AS jsonb_form;
-- Risultato: "Esempio di testo semplice"
JSONB → TEXT
SELECT info::TEXT AS text_form
FROM books_json;
-- Risultato: {"title": "SQL Base", "tags": ["principiante", "database"]}
HSTORE → JSONB
SELECT hstore_to_jsonb(attributes) AS jsonb_form
FROM products;
-- Risultato: {"colore": "rosso", "taglia": "M"}
JSONB → HSTORE
SELECT jsonb_to_hstore('{"colore": "rosso", "taglia": "M"}') AS hstore_form;
-- Risultato: "colore"=>"rosso", "taglia"=>"M"
A cosa fare attenzione?
Se ti serve la massima flessibilità e supporto per strutture complesse, scegli JSONB. Ma se il tuo caso è una struttura dati semplice, tipo array, testo o coppie "chiave-valore", usa il tipo di dato più adatto (ARRAY, TEXT, HSTORE).
Ricorda: scegliere la struttura dati giusta ti evita un sacco di grattacapi dopo e migliora le performance delle tue query.
GO TO FULL VERSION