Oggi dobbiamo capire meglio gli array e anche confrontarli più a fondo con JSONB, vedere i loro punti forti e deboli e scegliere le best practice per usarli nei casi reali.
Array vs JSONB: mini-tartarughine di dati vs flessibilità in una scatola
Ormai lo sai: negli array di PostgreSQL puoi salvare valori di un solo tipo di dato: array di numeri, stringhe o date. Esempio: una lista di voti di uno studente, dove tutti gli elementi sono numeri.
-- Tabella con studenti e i loro voti
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT,
grades INTEGER[] -- array di voti
);
JSONB, invece, è un modo per salvare dati come una struttura JSON. Sembra proprio un oggetto JavaScript, ma con il vantaggio di parsing e indicizzazione veloce. In JSONB puoi salvare sia liste ordinate che oggetti con chiavi e valori.
-- Tabella con studenti e vari dati su di loro
CREATE TABLE students_details (
id SERIAL PRIMARY KEY,
name TEXT,
details JSONB -- struttura JSON flessibile
);
Esempio di dati in JSONB:
{
"grades": [90, 82, 77],
"address": {
"city": "Berlin",
"zip": "352912"
}
}
Quindi, gli array sono un modo semplice per lavorare con liste di valori, mentre JSONB ti dà molte più possibilità per dati complessi.
Differenze principali tra array e JSONB
| Caratteristica | Array | JSONB |
|---|---|---|
| Tipo di struttura | Struttura dati lineare | Struttura dati gerarchica |
| Tipi di elementi | Solo un tipo di dato | Tipi di dati diversi |
| Dimensione della struttura | Fissa (lineare) | Flessibile, può includere liste e oggetti |
| Velocità di accesso | Alta con dati fissi | Più lenta con ricerche complesse |
| Indicizzazione | Supporta bene l’indicizzazione | Richiede indice tipo GIN |
| Utilizzo | Lista semplice o array di valori | Dati complessi: oggetti/list annidati |
Vediamo ora come funziona tutto questo nella pratica.
Quando usare gli array?
Supponiamo di avere un database di libri, dove ogni libro può appartenere a più generi. Qui l’array è una scelta ottima.
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
genres TEXT[] -- array di generi
);
-- Esempio di inserimento di un libro con più generi
INSERT INTO books (title, genres)
VALUES ('1984', ARRAY['Distopia', 'Fiction Politica', 'Fantascienza']);
Gli array sono ottimi se sei sicuro che:
- i tuoi dati possono essere salvati come una lista,
- le liste saranno piccole e omogenee (tipo stringhe o numeri),
- devi solo salvare ed estrarre liste (senza operazioni complesse).
Vantaggi degli array
- Semplicità nel salvare dati dello stesso tipo.
- Comodi per liste piccole, tipo tag, categorie o voti.
Quando usare JSONB?
Ora immaginiamo di voler salvare dati più complessi sui libri, inclusi generi, ISBN e rating. Qui gli array non bastano più — è il momento di JSONB.
CREATE TABLE books_details (
id SERIAL PRIMARY KEY,
title TEXT,
details JSONB -- dettagli del libro come JSONB
);
-- Esempio di inserimento di info complesse su un libro
INSERT INTO books_details (title, details)
VALUES (
'1984',
'{"genres": ["Distopia", "Fiction Politica", "Fantascienza"],
"isbn": "9780451524935",
"rating": 8.9}'
);
JSONB è ottimo se ti serve:
- salvare dati complessi o eterogenei (numeri, stringhe, liste, oggetti),
- aggiungere parametri dinamicamente senza cambiare la struttura della tabella,
- salvare dati annidati (tipo indirizzi, caratteristiche, impostazioni).
Vantaggi di JSONB
- Grande flessibilità. Puoi aggiungere nuove chiavi e valori senza cambiare la struttura della tabella.
- Perfetto per dati complessi, tipo risposte JSON da API.
Scegliere tra array e JSONB
Se devi salvare solo liste di dati omogenei — usa gli array. Per esempio:
-- Salvare gli ID dei partecipanti agli eventi
CREATE TABLE events (
id SERIAL PRIMARY KEY,
participant_ids INTEGER[]
);
Se i dati sono eterogenei o complessi — meglio JSONB. Per esempio:
-- Salvare info sui clienti con indirizzi
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
info JSONB
);
Per l’indicizzazione, array e JSONB hanno approcci diversi. Per gli array si usano spesso indici GIN, per JSONB — GIN e BTREE, a seconda della struttura dei dati.
Performance
Gli array sono più veloci per le ricerche tipiche. JSONB è un po’ più lento, ma vince in flessibilità. Se vuoi solo cercare elementi (tipo generi o ID), gli array sono più rapidi:
-- Usare array con indice GIN
CREATE INDEX idx_genres ON books USING GIN(genres);
-- Filtrare libri per genere
SELECT * FROM books WHERE genres @> ARRAY['Fantascienza'];
Verifica della presenza di dati
In JSONB hai più possibilità con i filtri sulle chiavi:
-- Verifica della presenza della chiave "genres"
SELECT * FROM books_details WHERE details ? 'genres';
-- Verifica della presenza di un elemento nella lista
SELECT * FROM books_details WHERE details->'genres' ?| ARRAY['Fantasy', 'Distopia'];
Negli array puoi cercare valori direttamente:
-- Verifica della presenza di un elemento nell’array
SELECT * FROM books WHERE genres @> ARRAY['Fantasy'];
Flessibilità delle strutture
JSONB è insostituibile se i dati hanno strutture annidate complesse:
{
"genres": ["Fantasy", "Avventura"],
"ratings": {"goodreads": 8.5, "amazon": 4.7}
}
Per gli array questo non è possibile senza normalizzazione o campi extra.
Alla fine, array e JSONB non sono rivali, ma strumenti per casi diversi. Se i dati sono tipo lista — vai di array. Se invece hai dati complessi, annidati o eterogenei — JSONB tutta la vita. L’importante è ricordarsi di performance e indicizzazione!
GO TO FULL VERSION