Database per principianti: SQL, Postgres e Supabase spiegati
Scopri come i database relazionali organizzano le informazioni, come funziona SQL e perché Postgres e Supabase vengono spesso usati insieme nelle moderne app web. La lezione tratta anche la progettazione degli schemi, la sicurezza e i flussi di lavoro pratici per i database in Coderblock.

Perché le app web hanno bisogno dei database

Un'applicazione può mostrare una schermata, raccogliere un dato o eseguire un'azione. Ma cosa succede quando deve ricordare qualcosa?
Una piattaforma di prenotazione deve ricordare clienti, servizi e appuntamenti. Un e-commerce deve gestire prodotti, ordini e inventario. Una piattaforma SaaS deve sapere quali utenti hanno un account, quali progetti hanno creato e quali permessi possiedono.
Per questo esistono i database.
Un database è il luogo in cui un'applicazione conserva le informazioni di cui ha bisogno in modo strutturato e persistente. Senza un database, molti dati potrebbero esistere soltanto temporaneamente nel browser. Chiudendo la pagina, potrebbero andare persi. Con un database, invece, l'app può salvare informazioni e recuperarle in un secondo momento, anche da dispositivi diversi e per utenti diversi.
Un database è la memoria dell'app
Puoi pensare al database come alla memoria permanente di un'applicazione.
Il frontend mostra le informazioni. Il backend applica la logica. Il database conserva i dati.
In un'app di prenotazione, per esempio:
Frontend → mostra servizi e calendario Backend → controlla disponibilità e permessi Database → conserva utenti, servizi e prenotazioni
Esistono diversi tipi di database. I database documentali lavorano con documenti flessibili, quelli key-value sono ottimizzati per determinati tipi di accesso rapido, mentre i database relazionali organizzano i dati in tabelle collegate tra loro. SQL e Postgres appartengono principalmente a questo mondo. Supabase, invece, costruisce intorno a Postgres un insieme di servizi backend pensati per le applicazioni web.
Database relazionali: tabelle, righe e relazioni
Un database relazionale organizza le informazioni in tabelle. Ogni tabella rappresenta generalmente un tipo di entità. In una piattaforma di prenotazione potresti avere:
profiles→ gli utenti;services→ i servizi disponibili;bookings→ le prenotazioni.
All'interno di ogni tabella trovi:
- colonne, che descrivono le proprietà dei dati;
- righe, che rappresentano i singoli record;
- chiavi primarie, che identificano ogni record in modo univoco;
- chiavi esterne, che collegano record appartenenti a tabelle diverse;
- vincoli, che impediscono di salvare dati non validi.
Per esempio, una prenotazione potrebbe contenere un profile_id e un service_id.
In questo modo sai esattamente chi ha effettuato la prenotazione e quale servizio ha scelto, senza dover copiare tutte le informazioni dell'utente e del servizio dentro ogni singola prenotazione.
Perché le relazioni sono importanti?
Immagina che un servizio cambi nome. Se il nome fosse copiato all'interno di ogni prenotazione, dovresti aggiornare centinaia o migliaia di record. Con un database relazionale, invece, la prenotazione può semplicemente fare riferimento al servizio corretto. La relazione tra i dati permette quindi di ridurre duplicazioni e incoerenze e di mantenere il modello del prodotto più ordinato.
Che cos'è lo schema di un database?
Prima di creare un database bisogna decidere come organizzare le informazioni. L'insieme di tabelle, colonne, relazioni, tipi di dati e vincoli che definiscono questa struttura viene chiamato schema. Progettare bene lo schema significa riflettere nel database il modo in cui funziona realmente il prodotto.
Prima di creare una nuova tabella, chiediti:
- Che cosa rappresenta ogni record?
- Quali informazioni sono obbligatorie?
- Quali valori devono essere univoci?
- Quali entità devono essere collegate?
- Chi può leggere o modificare questi dati?
L'obiettivo non è creare il maggior numero possibile di tabelle. Una tabella enorme con informazioni completamente diverse può diventare difficile da gestire. Allo stesso tempo, dividere ogni piccolo dato in una tabella separata può rendere il sistema inutilmente complesso.
Un buon schema trova un equilibrio tra coerenza dei dati, semplicità delle query e necessità reali del prodotto.
Che cos'è SQL?
A questo punto entra in gioco SQL, acronimo di Structured Query Language. SQL è il linguaggio utilizzato per interagire con molti database relazionali.
Puoi utilizzarlo per:
- creare strutture;
- leggere dati;
- aggiungere record;
- modificare informazioni;
- eliminare record;
- collegare dati provenienti da tabelle diverse.
Le quattro operazioni fondamentali vengono spesso riassunte con l'acronimo CRUD:
- Create → creare
- Read → leggere
- Update → aggiornare
- Delete → eliminare
Un esempio semplice
Supponiamo di voler recuperare le prenotazioni di un determinato utente. Una query SQL potrebbe essere:
SELECT id, start_time, status
FROM bookings
WHERE profile_id = 42
ORDER BY start_time;
In pratica stiamo dicendo:
“Dammi ID, orario e stato delle prenotazioni dell'utente 42, ordinate per orario.”
SQL permette anche di combinare informazioni provenienti da tabelle diverse. Per esempio:
SELECT bookings.start_time, services.name
FROM bookings
JOIN services ON services.id = bookings.service_id;
Questa query collega le prenotazioni ai servizi corrispondenti per poter ottenere, insieme all'orario, anche il nome del servizio.
SQL è dichiarativo
Una caratteristica importante di SQL è che è un linguaggio dichiarativo. Non devi necessariamente spiegare al database ogni singolo passaggio necessario per trovare un'informazione. Gli dici che risultato vuoi ottenere e il database decide come eseguire la query.
SQL è inoltre uno standard ampiamente utilizzato, anche se sistemi diversi possono avere funzionalità ed estensioni specifiche. Per iniziare non è necessario imparare tutto. Comprendere concetti come SELECT, filtri, JOIN, raggruppamenti, vincoli e transazioni è già sufficiente per costruire una buona base.
Che cos'è Postgres?
Qui è importante fare una distinzione: SQL è il linguaggio. Postgres è il database.
Postgres, o più precisamente PostgreSQL, è un sistema di gestione di database relazionali open source. È il software che conserva i dati, applica i vincoli e interpreta le query SQL.
Puoi quindi pensare alla relazione in questo modo:
SQL → il linguaggio con cui comunichi Postgres → il sistema che conserva e gestisce i dati
Postgres supporta funzionalità fondamentali come:
- chiavi primarie e chiavi esterne
- transazioni
- indici
- viste
- vincoli
- tipi di dati avanzati
Perché le transazioni sono importanti?
Immagina un e-commerce. Quando un cliente acquista un prodotto, il sistema potrebbe dover:
- creare l'ordine;
- ridurre l'inventario;
- registrare il pagamento.
Queste operazioni sono collegate. Se la prima va a buon fine ma la seconda fallisce, potresti ritrovarti con un ordine registrato ma un inventario non aggiornato.
Le transazioni permettono di trattare più operazioni come un'unica unità: o vengono completate correttamente, oppure il database può riportare la situazione allo stato precedente.
E gli indici?
Gli indici servono a rendere più veloci determinate ricerche. Se un'applicazione deve cercare continuamente le prenotazioni di un utente in una determinata data, un indice può rendere questa operazione molto più efficiente. Ma gli indici non sono gratuiti: occupano spazio e richiedono lavoro quando i dati vengono modificati.
Per questo non è una buona pratica indicizzare automaticamente ogni colonna. L'indice dovrebbe rispondere a una reale modalità di interrogazione del prodotto.
Che cos'è Supabase?
Se Postgres è il database, Supabase è una piattaforma backend costruita intorno a Postgres. Non sostituisce Postgres.
Aggiunge invece una serie di servizi che servono normalmente per costruire applicazioni web, tra cui:
- autenticazione e gestione delle sessioni;
- storage per i file;
- strumenti per amministrare il database;
- funzioni server-side;
- API collegate ai dati;
- Row Level Security.
La distinzione più importante da ricordare è quindi:
SQL è il linguaggio. Postgres è il database. Supabase è una piattaforma backend che utilizza Postgres e aggiunge servizi per costruire applicazioni.
Questa combinazione è particolarmente utile per app web perché permette di gestire dati, utenti, file e autorizzazioni all'interno di un'infrastruttura integrata.
Autenticazione e autorizzazione: due cose diverse
Anche qui è utile separare due concetti. Autenticazione significa:
“Chi è questo utente?”
Autorizzazione significa:
“Che cosa può fare questo utente?”
Supabase Auth può gestire registrazione, login e sessioni. La Row Level Security (RLS) può invece stabilire quali righe del database un determinato utente può leggere o modificare. Immagina una piattaforma di prenotazione. Un cliente dovrebbe poter vedere:
le proprie prenotazioni.
Un amministratore potrebbe invece vedere:
tutte le prenotazioni.
Entrambi sono utenti autenticati, ma hanno autorizzazioni diverse.
La sicurezza non può dipendere solo dal frontend
Nascondere un pulsante nell'interfaccia non significa impedire a qualcuno di eseguire un'operazione. Un utente potrebbe tentare di inviare direttamente una richiesta al backend.
Per questo le regole di accesso devono essere applicate nel backend e nel database, non soltanto nell'interfaccia. È proprio qui che la Row Level Security diventa importante: permette di definire le regole di accesso direttamente a livello di database.
Come funzionano i database in Coderblock
Nelle app web standard di Coderblock, ogni progetto dispone di un ambiente Supabase dedicato con Postgres, Auth, Storage, Deno Edge Functions e Row Level Security. Sono inoltre già presenti una struttura di base per i profili e un sistema iniziale per i ruoli.
La differenza è che non devi necessariamente partire configurando manualmente il database. Puoi descrivere ciò che vuoi costruire attraverso la chat.
Per esempio:
“Aggiungi servizi con durata, prezzo e stato attivo.”
Poi:
“Crea prenotazioni collegate agli utenti autenticati.”
E ancora:
“Impedisci ai clienti di vedere le prenotazioni degli altri clienti e crea una vista amministrativa per gestirle tutte.”
L'agente può progettare lo schema, applicare le migrazioni, collegare il frontend React al backend e configurare le policy RLS necessarie. Nella sezione Backend dell'editor puoi poi controllare tabelle, utenti autenticati, storage e funzioni.
La preview live si aggiorna mentre continui a modificare l'app attraverso la conversazione.
Il prompt migliore non è “crea un database”
Quando lavori con un AI app builder, non serve limitarsi a chiedere:
“Crea un database per un'app di prenotazioni.”
È molto più utile descrivere il modello del prodotto. Indica:
- quali sono le entità principali;
- quali informazioni devono contenere;
- come sono collegate;
- quali campi sono obbligatori;
- quali utenti possono accedere ai dati;
- quali azioni possono eseguire.
In questo modo l'AI ha le informazioni necessarie per trasformare una descrizione del prodotto in una struttura dati coerente.
Buone pratiche per iniziare con i database
Non serve essere un database engineer per evitare gli errori più comuni.
Usa identificatori stabili
Ogni tabella importante dovrebbe avere una chiave primaria. Evita di utilizzare dati come nomi o indirizzi email come identificatori permanenti: possono cambiare.
Metti le regole vicino ai dati
La validazione nel frontend è utile per l'esperienza dell'utente, ma non dovrebbe essere l'unica protezione. Utilizza:
- campi obbligatori;
- vincoli di unicità;
- chiavi esterne;
- tipi di dati appropriati;
- policy di accesso.
In questo modo il database può proteggere l'integrità dei dati indipendentemente da dove arriva una richiesta.
Segui il principio del privilegio minimo
Ogni utente dovrebbe avere soltanto i permessi necessari per svolgere il proprio lavoro. Testa quindi l'app con ruoli diversi:
- visitatore anonimo;
- utente autenticato;
- amministratore.
Verifica sempre cosa può leggere, creare, modificare o eliminare ciascun ruolo.
Gestisci lo schema attraverso migrazioni
I database cambiano insieme ai prodotti. Quando aggiungi una nuova funzionalità, potresti dover creare una tabella, aggiungere una colonna o modificare una relazione. Utilizzare migrazioni controllate permette di mantenere traccia di questi cambiamenti e riduce il rischio di perdere dati esistenti. Prima di eliminare una colonna o modificare una struttura, verifica sempre che non sia più utilizzata.
Modella il prodotto, non la schermata
Questa è forse la regola più importante. Una tabella dovrebbe rappresentare un concetto reale del prodotto, non semplicemente una schermata dell'interfaccia. Una dashboard può cambiare completamente design. Un cliente, una prenotazione o un ordine continuano invece a rappresentare le stesse entità. Pensare prima al modello dei dati rende più semplice anche evolvere il frontend in futuro.
SQL, Postgres e Supabase: cosa devi davvero ricordare
Se sei alle prime armi, non serve memorizzare decine di termini.
Tieni a mente questa relazione:
SQL → il linguaggio utilizzato per interrogare e modificare i dati Postgres → il database relazionale che conserva i dati ed esegue le query Supabase → la piattaforma backend che utilizza Postgres e aggiunge autenticazione, storage, API, funzioni e strumenti per costruire applicazioni web
In Coderblock, questi concetti vengono integrati nel processo di creazione dell'app. Puoi descrivere in linguaggio naturale cosa deve ricordare la tua applicazione, come devono essere collegati i dati e chi può accedervi. L'agente può occuparsi dell'implementazione full stack, mentre tu puoi controllare e perfezionare il risultato attraverso la chat.
Capire come funzionano i database ti permette quindi di fare qualcosa di ancora più importante: descrivere meglio ciò che vuoi costruire. Non devi necessariamente scrivere SQL. Ma sapere cosa sono tabelle, relazioni, ruoli, vincoli e autorizzazioni ti aiuta a trasformare un'idea in un'applicazione che non si limita a mostrare dati, ma sa davvero conservarli, collegarli e proteggerli.


