Skip to content

Capitolo 6: Database NoSQL & Teorema CAP (Brewer)

Il sesto modulo del corso analizza il passaggio dalle basi di dati relazionali tradizionali (RDBMS) alle architetture NoSQL (Not Only SQL), esaminando le quattro famiglie principali di modelli non relazionali e il Teorema CAP (di Brewer) che governa il bilanciamento tra coerenza, disponibilità e tolleranza ai guasti nei sistemi distribuiti su larga scala.


1. Dal Modello Relazionale al Paradigma NoSQL

Section titled “1. Dal Modello Relazionale al Paradigma NoSQL”

I Limiti dei Database Relazionali (RDBMS) in Scenari Big Data

Section titled “I Limiti dei Database Relazionali (RDBMS) in Scenari Big Data”

I database relazionali classici (come Oracle, MySQL o PostgreSQL) si fondano su regole strutturali molto rigide:

  • Schema predefinito a priori (Schema-on-Write): i dati devono essere organizzati in tabelle in cui ogni riga è univoca e ogni colonna ammette valori di un unico tipo predeterminato;
  • Inefficienza con dati sparsi: quando i dati raccolti non sono uniformi (ad esempio perché molti attributi sono presenti solo per alcuni utenti e assenti per altri), una tabella relazionale è costretta a memorizzare una grande quantità di valori NULL, causando un forte spreco di spazio su disco e un rallentamento delle query;
  • Costo computazionale dei JOIN e delle conversioni: quando i dati sono fortemente interconnessi o le applicazioni orientate agli oggetti devono interagire ad altissima frequenza con la base dati, le operazioni di JOIN tra più tabelle e la conversione continua tra record relazionali e oggetti applicativi diventano colli di bottiglia critici.

Quando Conviene Scegliere l’Approccio NoSQL

Section titled “Quando Conviene Scegliere l’Approccio NoSQL”

In generale, l’adozione di un database NoSQL risulta vantaggiosa quando ricorre almeno una delle seguenti quattro condizioni:

  1. Struttura dei dati non definibile a priori
    I dati in ingresso sono eterogenei, semi-strutturati o molto sparsi, rendendo impossibile o inefficiente disegnare a monte uno schema tabellare fisso.

  2. Dati fortemente interconnessi e superamento del JOIN
    I dati disposti nei vari oggetti presentano fitti legami reciproci per i quali il dispendioso operatore JOIN relazionale non è ottimale: conviene invece navigare direttamente tra gli oggetti sfruttando i riferimenti diretti tra i nodi di informazione.

  3. Interazioni ad altissima frequenza (assenza di conversioni Record/Oggetto)
    È necessario leggere e scrivere molto frequentemente sul database, evitando l’onere computazionale di convertire continuamente le righe di una tabella negli oggetti del linguaggio di programmazione.

  4. Esigenza di prestazioni elevate oltre i vincoli ACID
    Il dominio applicativo richiede velocità di risposta e scalabilità orizzontale estreme, rendendo accettabile allentare le rigide proprietà transazionali ACID (Atomicity, Consistency, Isolation, Durability) tipiche dei sistemi RDBMS.


1. Database Orientati ai Documenti (Document-Based DB)

Section titled “1. Database Orientati ai Documenti (Document-Based DB)”

Nei database a documenti la rappresentazione dei dati è affidata a strutture auto-contenute simili agli oggetti della programmazione, chiamate documenti (tipicamente serializzati in formato JSON, BSON o XML), ciascuno dei quali possiede un insieme di proprietà che descrivono le informazioni:

  • Assenza di struttura rigida (Schema-less): ogni documento può possedere campi e parametri differenti rispetto agli altri documenti della medesima collezione, eliminando alla radice il problema dei campi NULL;
  • Relazioni tramite riferimenti e navigazione ad albero: i documenti possono contenere sotto-documenti annidati oppure essere collegati tra loro mediante riferimenti diretti. Ad esempio, un documento radice <<documento>> Sedi Lombardia può puntare ai documenti <<documento>> Sede Milano1 e <<documento>> Sede Milano2, i quali a loro volta puntano ai documenti dei singoli dipendenti (Rossi Paolo, Grigi Enea, Verdi Elena, Bianchi Lorena, Gialli Carlo);
  • Modalità di interrogazione: non essendoci uno schema fisso definito a priori, lo schema viene navigato ad albero; se un’applicazione richiede un campo non presente in uno specifico documento, il sistema restituisce semplicemente che quel campo non è disponibile per quel nodo, mentre l’operazione più comune consiste nell’estrarre e visualizzare l’intero documento con tutti gli attributi che possiede;
  • DBMS di riferimento: MongoDB, CouchDB.
// Esempio di documento JSON/BSON in MongoDB con sotto-documento annidato
{
"_id" : ObjectId("57bdd4a1eb426816499fb1be"),
"Titolo" : "Promessi Sposi",
"Autore" : "Alessandro Manzoni",
"Pubblicazione" : {
"Editore" : "PremiateEdizioni",
"Anno_pubblicazione" : 2012,
"Numero_pagine" : 732
}
}

I database Key-Value adottano il modello di archiviazione più snello e veloce:

  • Coppie (Chiave, Valore): i dati sono inseriti due valori alla volta, ossia una chiave univoca (Key) che funge da indice diretto e il valore (Value) ad essa associato (che può essere un tipo primitivo o una struttura complessa come una HashMap);
  • Altissima velocità di ricerca: grazie all’indicizzazione diretta sulla chiave, sono la soluzione d’elezione quando si devono effettuare ricerche puntuali e frequentissime su un’enorme mole di dati con latenza minima;
  • DBMS di riferimento: Redis, Cassandra.

In un database relazionale tradizionale, l’anagrafica di un utente è suddivisa su più colonne di una tabella rigida:

idnomecognomeindirizzocittàCAP
123456GiulioRossiVia Monte Bianco 78Torino10100

3. Database Orientati alle Colonne (Column-Based / Wide-Column DB)

Section titled “3. Database Orientati alle Colonne (Column-Based / Wide-Column DB)”

A differenza dei database relazionali (che memorizzano fisicamente i dati riga per riga), i database Column-Based organizzano e archiviano i dati per colonna anziché per riga:

  • Column Family (Famiglia di Colonne): le colonne correlate sono raggruppate in contenitori logici detti Column Family, e ogni Column Family viene scritta fisicamente su un file diverso;
  • Row Key e puntatori multipli: ogni riga dispone di una chiave primaria (Row Key) che può puntare a diverse famiglie di colonne, all’interno delle quali risiedono le coppie (Column Key, Column Value) pertinenti a quella specifica riga;
  • Caso d’uso: particolarmente efficace quando lo schema non è interamente noto a priori e si devono eseguire scansioni o aggregazioni veloci su specifici sottoinsiemi di attributi; nella pratica è spesso combinato con il modello Key-Value;
  • DBMS di riferimento: Apache HBase, Apache Cassandra.
Esempio di struttura Column-Family Database (Slide 12):
┌─── Column Family: Customer ───────────────┐
│ Column Key Column Value │
┌─────►│ Name : Mak │
│ │ Address : 13th, Avenue │
│ │ Payment : Check │
┌───────────────┐ │ └───────────────────────────────────────────┘
│ Row Key: 3425 │────┤
└───────────────┘ │ ┌─── Column Family: Orders ─────────────────┐
│ │ Column Key Column Value │
└─────►│ OR1 : Laptop HP │
│ OR2 : Samsung Mobile │
│ OR3 : Notebook │
│ OR4 : Stationary │
└───────────────────────────────────────────┘

Nei database a grafi la struttura dati è modellata direttamente come un grafo orientato composto da nodi (entità) e archi (relazioni), in cui le informazioni possono essere custodite sia nei nodi sia negli archi:

1. Direzione dell'Arco

Gli archi sono orientati: un collegamento che va dal nodo AA al nodo BB (A→BA \to B) non equivale né a un collegamento in senso opposto (B→AB \to A) né a un collegamento bidirezionale (A↔BA \leftrightarrow B).

2. Significato Semantico (Label)

Ogni arco possiede un’etichetta (Label) che qualifica il rapporto di dipendenza, appartenenza o conoscenza tra i due nodi (es. knows, is_member, Members).

3. Proprietà sull'Arco

Gli archi stessi memorizzano attributi chiave-valore: ad esempio, se due nodi rappresentano due città, l’arco che li congiunge può memorizzare la distanza chilometrica (o il tempo di percorrenza), permettendo di calcolare direttamente il percorso più breve o più veloce.

  • Esempio di Grafo Sociale (Slide 15):
    • Nodi: Id: 1 (Name: Alice, Age: 18), Id: 2 (Name: Bob, Age: 22) e Id: 3 (Type: Group, Name: Chess).
    • Archi orientati con attributi:
      • Dal nodo Alice al nodo Bob parte l’arco Id: 100 con Label: knows e proprietà Since: 2001/10/03, mentre da Bob verso Alice parte un arco distinto Id: 101 con Label: knows e Since: 2001/10/04;
      • Sia Alice sia Bob sono collegati al nodo gruppo Chess tramite archi is_member (con la rispettiva data di iscrizione Since: 2005/07/01 e Since: 2011/02/14) e archi inversi Members che partono dal gruppo verso i singoli membri.
  • Quando utilizzarli: quando i dati sono fortemente correlati e l’informazione associata al collegamento ha un’importanza pari o superiore a quella contenuta nel nodo stesso (reti sociali, routing stradale e logistico, motori di raccomandazione).
  • DBMS di riferimento: OrientDB, Neo4j.

Formulato dall’informatico Eric Brewer, il Teorema CAP enuncia una legge fondamentale dei sistemi distribuiti:

È impossibile per un sistema informatico distribuito fornire simultaneamente tutte e tre le seguenti garanzie:

  1. Consistency (Coerenza — C)
  2. Availability (Disponibilità — A)
  3. Partition Tolerance (Tolleranza alle partizioni — P)

Quando una banca dati distribuita deve gestire un volume molto ampio di informazioni garantendo prestazioni elevate su un’infrastruttura di rete non immune da guasti, può soddisfare al massimo due di queste tre proprietà contemporaneamente, obbligando il progettista a sacrificarne una.

ProprietàSignificato TecnicoImplicazione Pratica a Lezione
C — Consistency (Coerenza)Garanzia che ogni nodo in un cluster distribuito restituisca sempre il dato più recente (l’ultima versione aggiornata).Nessun nodo può rispondere a un’interrogazione restituendo una versione vecchia (stale) del dato perché non ha ancora completato l’allineamento con gli altri nodi.
A — Availability (Disponibilità)Garanzia che ogni richiesta riceva sempre una risposta entro l’intervallo di tempo utile previsto dal sistema.Nella maggior parte dei sistemi reali, una risposta eccessivamente ritardata è altrettanto negativa quanto una risposta non data (equivale a un’indisponibilità del servizio).
P — Partition Tolerance (Tolleranza alle partizioni)Garanzia che il sistema continui a funzionare anche quando un nodo cade o i messaggi sulla rete tra i nodi subiscono perdite o ritardi.Grazie alla replicazione dei record tra i nodi, il cluster assorbe interruzioni intermittenti o guasti parziali senza interrompere l’operatività complessiva.

Le Tre Combinazioni Architetturali: CA, CP e AP

Section titled “Le Tre Combinazioni Architetturali: CA, CP e AP”

A seconda della proprietà che si sceglie di sacrificare, i database si suddividono in tre famiglie architetturali:

Consistency + Availability (RDBMS Tradizionali: Oracle, MySQL)

  • Funzionamento: i dati sono mantenuti costantemente coerenti su tutti i nodi del cluster ed è sempre possibile leggere e scrivere su qualsiasi nodo con la certezza che il nuovo dato sia propagato ovunque, a condizione che tutti i nodi e la rete siano perfettamente funzionanti.
  • Limite (Sacrificio della Partition Tolerance): in un sistema relazionale non appositamente ridondato, se un nodo o un collegamento di rete cade, il sistema si blocca per non violare la coerenza. Inoltre, l’obbligo di mantenere la coerenza totale incide negativamente sulla latenza e sulla scalabilità orizzontale.

Modello / CategoriaStruttura del DatoCaso d’Uso IdealeEsempi di DBMSPosizionamento CAP Tipico
Relazionale (RDBMS)Tabelle rigide (righe e colonne tipizzate a priori)Transazioni strutturate a basso/medio volume con vincoli ACIDOracle, MySQLCA (sacrifica Partition Tolerance)
NoSQL a DocumentiDocumenti auto-contenuti (JSON / BSON / XML) navigabili ad alberoDati sparsi o privi di schema definibile a prioriMongoDB, CouchDBCP (MongoDB) / AP (CouchDB)
NoSQL Key-ValueCoppie (Chiave, Valore) indicizzate direttamenteRicerche puntuali ad altissima frequenza e velocitàRedis, CassandraAP / CP
NoSQL Column-BasedRow Key che punta a diverse Column Family (ognuna su file distinto)Grandi volumi distribuiti con letture/aggregazioni selettive per colonnaHBase, CassandraCP (HBase) / AP (Cassandra)
NoSQL a GrafiNodi e Archi orientati (con direzione, significato e proprietà sull’arco)Dati fortemente interconnessi, reti sociali, calcolo del percorso ottimoOrientDB, Neo4jVariabile (Multi-modello)