Perché il modello relazionale non basta più?
I database relazionali sono nati negli anni ’70 per gestire dati strutturati, transazioni bancarie, sistemi ERP. Per decenni hanno dominato. Ma con l’avvento del Web 2.0, dei social network e dell’IoT, sono emerse esigenze radicalmente nuove: miliardi di record, dati semi-strutturati o privi di schema fisso, scalabilità su decine di server, scritture continue a ritmo elevatissimo.
Il modello relazionale mostra i suoi limiti in questi scenari:
- Schema rigido: ogni modifica alla struttura (ALTER TABLE) è costosa e rischiosa su tabelle da miliardi di righe
- JOIN costosi: su dataset enormi le operazioni di join diventano proibitive in termini di CPU e I/O
- Scalabilità verticale: un RDBMS scala bene aumentando la potenza di un singolo server, ma ha un tetto fisico; scalare orizzontalmente (più macchine) è complesso e spesso non supportato nativamente
- Impedance mismatch: i dati nel codice (oggetti, JSON, array annidati) hanno una forma diversa da quella tabulare → serve una traduzione costante (ORM)
Il termine NoSQL compare ufficialmente nel 2009 in un meetup a San Francisco organizzato da Johan Oskarsson per discutere di database non relazionali distribuiti. Non significa “contro SQL”, ma “Not Only SQL“: esistono scenari in cui il modello relazionale non è la scelta ottimale.
ACID vs BASE: due filosofie a confronto
I RDBMS tradizionali garantiscono le proprietà ACID, che assicurano la correttezza assoluta dei dati in ogni circostanza. I sistemi NoSQL spesso adottano un modello più rilassato chiamato BASE, che sacrifica la consistenza immediata in favore della disponibilità e della scalabilità.
Su Facebook, se aggiorni il tuo stato, un tuo amico in un altro continente potrebbe vedere la versione precedente per qualche secondo. Questo è “eventually consistent“: i dati alla fine saranno coerenti, ma non istantaneamente. Per un social network è accettabile. Per un bonifico bancario no.
Il teorema CAP
Il teorema CAP (Brewer, 2000) afferma che un sistema distribuito può garantire al massimo due delle tre proprietà: Consistency (tutti i nodi vedono gli stessi dati), Availability (ogni richiesta riceve una risposta), Partition Tolerance (il sistema funziona anche se la rete si divide).
Poiché le partizioni di rete in un sistema distribuito sono inevitabili, la scelta reale è tra CP (consistenza + tolleranza partizionamento) e AP (disponibilità + tolleranza partizionamento).
- RDBMS tradizionali (CA): MySQL, PostgreSQL — ottimi su un singolo nodo, ma scalabilità orizzontale complessa
- CP: MongoDB (write concern majority), HBase, Zookeeper — consistenza prioritaria
- AP: CouchDB, Cassandra, DynamoDB — disponibilità prioritaria, eventual consistency
Le quattro categorie NoSQL
1. Document Store
Embedding vs Referencing: in MongoDB puoi includere dati correlati direttamente nel documento (embedding) oppure usare riferimenti a ID di altri documenti (referencing). L’embedding è ottimo per dati strettamente correlati e acceduti insieme; il referencing è preferibile quando i dati sono condivisi tra molti documenti.
| Aspetto | SQL (tabella ORDINI) | MongoDB (documento) |
|---|---|---|
| Struttura | Righe con colonne fisse | Documento JSON annidato |
| Relazioni | JOIN su chiave esterna | Embedding o $lookup |
| Schema | Fisso (ALTER TABLE) | Flessibile (schema-less) |
| Uso tipico | Sistemi transazionali | CMS, e-commerce, profili utente |
2. Key-Value Store
Casi d’uso tipici di Redis:
- Cache applicativa: risultati di query SQL costose memorizzati in Redis → risposta in microsecondi invece di millisecondi
- Sessioni utente: dati di login con TTL automatico (EX = expire after N secondi)
- Contatori in tempo reale: like, visite, messaggi non letti
- Code di lavori (job queue): produttore inserisce task, consumatore li estrae con LPOP/BRPOP
- Pub/Sub: notifiche real-time tra microservizi
3. Column-Family Store
4. Database a Grafo
Casi d’uso tipici:
- Social network: “persone che potresti conoscere” (amici degli amici)
- Fraud detection: rilevare pattern anomali tra transazioni e account
- Knowledge graph: Wikipedia, Google Knowledge Graph
- Motori di raccomandazione: Netflix, Amazon (“chi ha visto X ha visto anche Y”)
Riepilogo: quando scegliere SQL vs NoSQL?
| Criterio | Scegli SQL | Scegli NoSQL |
|---|---|---|
| Schema dei dati | Fisso, strutturato, relazionale | Flessibile, variabile, semi-strutturato |
| Consistenza | Critica (transazioni finanziarie) | Eventual consistency accettabile |
| Scalabilità | Verticale (scale-up) | Orizzontale (scale-out, sharding) |
| Tipo di query | Query complesse con JOIN multipli | Accesso per chiave, aggregazioni massive |
| Volume dati | Da KB a decine di GB | Da GB a petabyte |
| Velocità scrittura | Moderata (overhead ACID) | Molto alta (nessun lock globale) |
| Esempi applicativi | ERP, banca, e-commerce tradizionale | Social media, IoT, analytics, gaming |
Molte architetture moderne usano entrambi: PostgreSQL per i dati transazionali (ordini, pagamenti), Redis come cache e per le sessioni, MongoDB per i cataloghi prodotti, Elasticsearch per la ricerca full-text. Si chiama Polyglot Persistence: usare il DB giusto per ogni tipo di dato.
- I DB NoSQL nascono per rispondere ai limiti del modello relazionale: schema rigido, difficoltà di scalabilità orizzontale, join costosi su big data
- ACID garantisce correttezza assoluta (usato da RDBMS); BASE sacrifica la consistenza immediata per guadagnare disponibilità e scalabilità (usato da NoSQL)
- Il teorema CAP dimostra che un sistema distribuito può garantire al massimo due tra Consistency, Availability e Partition Tolerance
- Quattro categorie NoSQL: Document store (MongoDB), Key-Value (Redis), Column-family (Cassandra), Graph (Neo4j)
- La scelta SQL vs NoSQL dipende dal tipo di dato, dalla consistenza richiesta, dal volume e dal pattern di accesso
- In produzione si usa spesso polyglot persistence: più DB specializzati per esigenze diverse nella stessa applicazione