Sei sulla pagina 1di 28

Database relazionali e NoSQL a confronto

Dimitri De Franciscis

10 aprile 2013
Sommario
Scopo di questo lavoro `e esplorare le possibilit`a offerte dai database appartenenti al
movimento NoSQL e confrontarli, dove possibile, con soluzioni pi` u tradizionali di tipo
relazionale (RDBMS ).
Nella prima parte verranno introdotte le varie categorie di database NoSQL, le loro
peculiarit`a, i problemi che risolvono e alcune delle nuove sfide che pongono. Nella sec-
onda parte verr` a effettuata lanalisi di alcuni scenari, confrontando di volta in volta
unimplementazione di tipo relazionale con la tecnologia NoSQL ritenuta pi` u adatta.
Si `e volutamente scelto uno stile pragmatico e, nei limiti consentiti dalla lunghezza
dellelaborato, simile nella struttura ad uno studio di fattibilit`a adatto ad una piccola-
media azienda di sviluppo software che sia intenzionata a valutare lutilizzo di NoSQL
per i propri prodotti.
Lelaborato `e nato come progetto desame per il corso di Complementi di Basi di Dati
tenuto dal dott. Andrea Maurino presso lUniversit`a degli Studi di Milano-Bicocca.

Revisioni del documento


Versione Data Commenti
1 11/02/2013 Versione iniziale
2 10/04/2013 Correzioni al testo e integrazioni

Licenza
Questopera `e distribuita con la seguente licenza:
Creative Commons Attribution 3.0 Unported License
http://creativecommons.org/licenses/by-nc-sa/3.0/

Lautore si impegna a rendere disponibile con licenza Creative Commons e aggiornata


lopera sul proprio sito web:
http://www.megadix.it/

i
Indice

I. Introduzione a NoSQL 1

1. Introduzione 3
1.1. Una definizione di NoSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Aspetti controversi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2. Caratteristiche dei database NoSQL 5


2.1. Classificazione in base al modello dei dati . . . . . . . . . . . . . . . . . . 5
2.1.1. Categorie di modelli di dati . . . . . . . . . . . . . . . . . . . . . . 5
2.1.2. Modello di dati key-value . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.3. Modello di dati Column Family . . . . . . . . . . . . . . . . . . . . 8
2.1.4. Modello di dati Document Store . . . . . . . . . . . . . . . . . . . 10
2.1.5. Modello di dati a Grafo . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2. Modelli di distribuzione, consistenza dei dati e CAP Theorem . . . . . . . 16
2.3. Modelli di distribuzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.1. Single Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.2. Replicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.3. Sharding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4. CAP Theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.5. Rilassamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.5.1. Rilassamento di Atomicit`a e Isolamento . . . . . . . . . . . . . . . 17
2.5.2. Rilassamento della Durabilit`a . . . . . . . . . . . . . . . . . . . . . 19
2.5.3. Eventual Consistency . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5.4. Perche il rilassamento . . . . . . . . . . . . . . . . . . . . . . . . . 20

3. Bibliografia 21

iii
Parte I.

Introduzione a NoSQL

1
1. Introduzione
1.1. Una definizione di NoSQL
Con il termine NoSQL si raggruppano varie tecnologie di persistenza dei dati, anche
molto diverse fra loro. Lacronimo stesso `e piuttosto vago e soggetto a varie interpre-
tazioni, di cui la pi`
u rilevante e accettata sembra essere Not Only SQL. Per stabilire
un punto di partenza, considereremo linterpretazione fornita da Pramod e Fowler in
NoSQL Distilled [1]:

Un insieme poco definito di database principalmente open-source, princi-


palmente sviluppati nel XXI secolo, principalmente che non fanno uso di
SQL.

Per completare questa definizione dobbiamo aggiungere anche che:

non utilizzano il modello relazionale;

non hanno (solitamente) uno schema esplicito, ovvero specificato utilizzando un


qualsiasi linguaggio formale;

la maggior parte di essi `e stata progettata da subito per funzionare bene in


cluster.

1.2. Aspetti controversi


Il termine NoSQL a partire dal 2009 `e diventato sempre pi` u una buzzword, ovvero una
parola molto di moda e utilizzata a sproposito, soprattutto nelle attivit`a di marketing;
a peggiorare la situazione, aggiungendo ulteriore confusione, si sono aggiunte molte idee
sbagliate a proposito di NoSQL.
Fra le argomentazioni a favore di NoSQL, rispetto al modello relazionale:

maggiori performance;

maggiore libert`
a e facilit`
a nello sviluppo;

minore impedance mismatch 1 ;


1
Per impedance mismatch si intende la differenza fra il modello relazionale e le strutture dati uti-
lizzate dallapplicazione ed effettivamente presenti in memoria. Le conseguenze principali di ques-
ta discrepanza sono 1) una maggior complessit` a dello strato di accesso ai dati e 2) degrado delle
performance.

3
1. Introduzione

minore sforzo di amministrazione.

Ovviamente non mancano le critiche, rivolte principalmente ai compromessi da ac-


cettare per poter utilizzare questa nuova classe di database (che tratteremo pi`
u in
dettaglio nel paragrafo 2.5 dedicato al Rilassamento):

nessuna garanzia di tipo ACID e conseguente impossibilit`a di implementare transazioni;

prodotti troppo giovani per soluzioni che necessitano di affidabilit`a e elevati


uptime;

livelli di sicurezza non certificati.

Nel corso della trattazione vedremo come il mondo NoSQL sia decisamente variegato
e che non ci siano prodotti sovrapponibili al 100%, cercheremo quindi di affrontare
queste argomentazioni (sia pro che contro) da un punto di vista il pi` u pratico possibile,
confrontando eventuali rischi e benefici delle varie soluzioni.
Una delle conclusioni di [1], pienamente condivise dallautore della presente pubbli-
cazione, `e che lo sviluppo software stia progressivamente passando ad un modello di per-
sitenza poliglotta (Polyglot Persistence), in grado di utilizzare lo strumento pi` u adatto
alle esigenze, il contesto e le sfide che pone il mercato. NoSQL `e dunque da considerarsi,
in questottica, una freccia in pi`u al proprio arco di chi desidera (o ha necessit`a di) fare
innovazione.

4
2. Caratteristiche dei database NoSQL
2.1. Classificazione in base al modello dei dati
Dal punto di vista degli utilizzatori (sviluppatori, amministratori, utenti di terminale,
ecc.) una delle caratteristiche peculiari dei database relazionali, nonche uno dei motivi
del loro grande successo, `e luniformit`a dellinterfaccia fra i dati e le applicazioni. Anche
confrontando diversi vendor, praticamente lunico modello dei dati utilizzato `e quello di
tipo tabulare, accessibile tramite SQL o stored procedure basate comunque su concetti
relazionali.
Avere un modello cos` stabile ha reso possibile non solo il consolidamento di alcune
best practice di sviluppo e gestione, ma anche un confronto diretto sul terreno delle
prestazioni, della scalabilit`
a, della sicurezza. I database catalogati come NoSQL, al con-
trario, utilizzano vari e diversi modelli dei dati. Questa differenziazione `e ovviamente il
frutto di precise scelte progettuali: per ottenere migliori performance, per fornire nuove
e migliori API (Application Program Interface) alle applicazioni, e cos` via. Questa di-
versit`a ci costringe inevitabilmente ad affrontare separatamente lanalisi dei vari modelli
dei dati, cercando di evidenziarne il campo di applicazione e i parametri di valutazione
per un eventuale adozione allinterno dei propri progetti.
Una nota a parte va per quei vendor, tradizionalmente considerati relazionali che,
gi`a da diversi anni ormai, propongono soluzioni innovative. Fra questi possiamo citare
alcuni giganti come Oracle (Oracle XML DB [6]), IBM (NoSQL Support for DB2 [5]) ma
anche progetti open source (PostgreSQL Hstore [4]). Questi prodotti in generale meno
utilizzati rispetto agli engine relazionali dei rispettivi produttori e, in ogni caso, cercano
di essere associati al movimento NoSQL per ovvi motivi di visibilit`a commerciale.

2.1.1. Categorie di modelli di dati


Possiamo identificare due macro-categorie:

modelli aggregate-oriented :
Key-Value store (2.1.2);
Column-Family (2.1.3);
Document (2.1.4);

modelli a Grafo (2.1.5).

Laggregato (Aggregate) `e un concetto fondamentale del Domain-Driven Design [2];


rappresenta una collezione di oggetti, raggruppati al di sotto di unentit`a radice, che

5
2. Caratteristiche dei database NoSQL

`e possibile trattare come un oggetto unico, e le cui singole parti non sono separabili.
Questo concetto `e applicato, nei database del primo gruppo, in vari modi e a vari livelli di
complessit` a; ci`
o, se da un lato complica ulteriormente il confronto fra prodotti, dallaltro
amplia il paniere delle soluzioni di persistenza a disposizione delle applicazioni.
Vedremo ora in dettaglio i vari modelli di dati. E` importante sottolineare che qui e nel
resto della pubblicazione i prodotti citati come esempio sono solo un piccolo sottoinsieme
di quelli effettivamente esistenti, e che la presente ricerca non ha pretese di esaustivit` a.

2.1.2. Modello di dati key-value


La caratteristica principale di questo modello `e sicuramente la semplicit`a delle strutture
dati, che sono sono appiattite in coppie chiave-valore1 . In sostanza lutilizzatore
vede la base dati come una grossa hash table contenente oggetti di vario tipo
(principalmente valori primitivi come numeri o stringhe), accessibili per chiave primaria.
Questo appiattimento, in ossequio al principio fondamentale dellinformatica Semplice
`e veloce, rende possibili altissime performance (tipicamente in lettura), facilitando al
tempo stesso il lavoro di distribuzione del carico su pi` u macchine (partizionamento o
sharding) per realizzare una scalabilit`a quasi lineare. Lindirizzamento di tipo hash
infatti consente di ottenere un costo di accesso molto basso, tipicamente compreso fra
O(1) (analsi ammortizzata nel caso di un fattore di riempimento non troppo elevato) e
O(log(n)), dove n uguale al numero di dati presenti nello storage.

Progettazione della chiave primaria

In questo tipo di database la progettazione della chiave primaria `e di fondamentale im-


portanza. Il motivo `e che essendo lo storage basato su indirizzamento diretto (chiavi
hash) non permette lesecuzione efficiente di ricerche e ordinamenti. Molti Key-Value
store ormai permettono la creazione di indici secondari (tramite B+Tree o loro varianti)
e full-text, ma ci`o `e deleterio per le performance (soprattutto in scrittura), senza contare
che complica la gestione di sharding e clustering, oltre che della consistenza. La doc-
umentazione di Riak (Secondary Indexes in Riak [14]) presenta questa relativamente
nuova caratteristica, rivelando alcuni dettagli implementativi e spiegando le difficolt` a
(soprattutto a livello teorico) da superare per ottenere il giusto equilibrio fra funzion-
alit`a, semplicit`
a duso e affidabilit`a. Unintroduzione pi`u pratica `e invece fornita dalla
presentazione Querying Riak Just Got Easier di Rusty Klophaus [15].
Il modo migliore per sfruttare al massimo le performance di questi prodotti rimane
dunque conoscere in anticipo le chiavi che si intendono utilizzare, eventualmente uti-
lizzando chiavi naturali o meccanismi distribuiti come UUID (Universally Unique Iden-
tifier ), che permettono di non dover dipendere da unautorit`a centrale per la generazione
delle stesse.
In figura 2.1 vediamo come esempio il database di unagenzia di viaggi.
1
`e possibile inserire un oggetto strutturato serializzandolo (JSON, XML, binario, ecc.), ma comunque
il Key-Value store lo vedr`a come un corpus unico, un aggregato appunto

6
2.1. Classificazione in base al modello dei dati

Figura 2.1.: Esempio di contenuti Key-Value

Persistenza dei dati

Una delle principali differenze fra le varie implementazioni `e data dalle caratteristiche
di Durabilit`
a (Durability). Molti Key-Value store infatti sono nati molto tempo fa, ma
venivano chiamati con nomi come cache applicative o acceleratori di applicazion-
i, avevano dunque (e hanno ancora) un unico scopo: conservare in memoria primaria
(RAM) i dati acceduti pi` u spesso o poco variabili. Molte implementazioni quindi non sal-
vano, per scelta, i dati in memoria secondaria2 (disco), che quindi non sopravviverebbero
ad un crash del processo. Analizzeremo pi` u in dettaglio questo aspetto nel paragrafo
2.5.2.
Alcuni esempi di Key-Value store:

implementazioni cache-only o volatili : EHCache[7], Memcached[8], Redis[9];

implementazioni persistenti, ovvero che salvano i dati fisicamente in memoria


secondaria (dischi o altro): Amazon SimpleDB[10], Berkley DB[11], EHCache,
MemcacheDB[12], Redis, Riak[13].

Come si pu`o notare, alcuni elementi compaiono pi` u volte. Redis, ad esempio, `e usato
principalmente come database RAM-only, ma ha la possibilit`a di sincronizzare i dati
su disco in vari modi, con diverse garanzie di affidabilit`a. Anche EHCache utilizza la
persistenza come meccanismo di failover ma, data la sua vocazione di cache applicativa
(come si evince dal nome), `e principalmente utilizzata come strumento di ottimizzazione
dopo un restart dellapplicazione3 .

2
ignorando volutamente gli inevitabili meccanismi di paging della memoria, forniti in maniera
trasparente dal sistema operativo.
3
in sostanza evita di dover ricaricare tutti i dati nella cache dal database vero

7
2. Caratteristiche dei database NoSQL

Campi di applicazione
Abbiamo visto come il campo di applicazione pi` u ovvio per i Key-Value store sia come
cache applicativa, ad esempio per memorizzare sessioni web o carrelli della spesa. Le
loro possibilit`
a per` o non finiscono qui; sempre pi`
u spesso infatti vengono utilizzati come
motore di storage per le applicazioni cosiddette BigData, ovvero calcolo massicciamente
parallelo e di grandi dimensioni, vedi ad esempio Apache Hadoop[16]. Fondamentale in
questi sistemi `e il supporto a computazioni che seguono il pattern MapReduce[17] il cui
partner ideale `e proprio un database semplice / poco strutturato, dalle performance alte
e costanti, distribuito, affidabile. Tutte caratteristiche che il modello Key-value soddisfa
in pieno.

2.1.3. Modello di dati Column Family


Questo modello pu` o essere visto come unevoluzione del Key-Value store, i dati infatti
vengono organizzati ancora come una hash table, ma utilizzando generalmente due o
pi`u livelli di indicizzazione. Il nome Column Family deriva dal fatto che la chiave
pi`
u esterna, detta row key perche identifica laggregato (pi`
u o meno lequivalente di una
riga di una tabella relazionale), mappa a sua volta una tupla costituita dalle colonne
dellaggregato stesso. In un certo senso `e come se le tabelle crescessero orizzontalmente
(nel senso delle colonne) invece che verticalmente (righe).
Alcuni esempi di Column-Family store sono Cassandra[18] e HBase[19]. Una grande
spinta alla ricerca sui database column-oriented `e stata data dallarticolo [20].

Standard Column Family Store


Il modello che abbiamo descritto nel paragrafo precedente `e alla base dei Column-Family
store e prende il nome di Standard Column Family. In figura 2.2 possiamo vedere com`e
strutturato.
Alcune osservazioni importanti sulla struttura dei dati:
come per i Key-Value store, i valori possono essere stringhe o, se limplementazione
lo permette, altri tipi di dati primitivi ;
ogni aggregato pu`
o avere un qualsiasi insieme di attributi;
non c`e uno schema formale, ovvero una specifica che elenchi gli attributi obbliga-
tori e il loro tipo.

Super Column Family Store


Unestensione dello Standard Column Family Store `e rappresentato dal Super Column
Family Store. Questo modello semplicemente aggiunge un ulteriore livello di indiciz-
zazione fra la row key e linsieme delle colonne, la cosiddetta super column. Questa
chiave viene utilizzata per raggruppare attributi correlati fra di loro, appartenenti allo
stesso aggregato, si potrebbe quindi considerare alla stregua di un insieme di view su
pi`
u tabelle in un database relazionale. Questa organizzazione ha vari vantaggi:

8
2.1. Classificazione in base al modello dei dati

Figura 2.2.: Standard Column Family Store

permette di avere una base dati pi`


u ordinata e facilmente utilizzabile dalle appli-
cazioni;

facilita limplementazione di strategie di partizionamento (sharding) efficienti;

come succede per i tablespace nel mondo relazionale, facilita la gestione di aspetti
come sicurezza e affidabilit`
a, suddividendo la base dati in segmenti pi` u piccoli e
maneggevoli.

In figura 2.3 possiamo vedere una rappresentazione di questo modello.

Vantaggi rispetto a Key-Value store


La struttura a pi` u livelli dei Column-Family store consente di realizzare funzioni di
ricerca pi`
u avanzate rispetto a Key-Value, perche la suddivisione fisica dei dati si presta
facilmente allindicizzazione e al partizionamento dei dati.

Campi di applicazione
Anche il modello Column-Family ha grande successo nel campo BigData, potendo fornire
un modello logico pi`u organizzato e flessibilie. Inoltre, proprio per la sua maggiore adat-
tabilit`a a modelli di dati ricchi, `e sempre pi`u spesso utilizzato al posto del modello

9
2. Caratteristiche dei database NoSQL

Figura 2.3.: Super Column Family Store

relazionale in campi come: siti web ad alto traffico, web service, come backend di appli-
cazioni mobile. Infine, grazie alla facilit`a con cui si possono partizionare i dati e la con-
seguente possibilit`
a di ottimizzare moltissimo le scritture, spesso i Column-Family store
sono utilizzati per memorizzare log applicativi, statistiche per analytics e monitoring,
audit di vario genere.

2.1.4. Modello di dati Document Store


Come il nome stesso fa intendere, i database in questa categoria gestiscono i dati uti-
lizzando la metafora del documento. Anche in questo caso abbiamo a che fare con un
aggregato ma, a differenza dei modelli visti finora, questo aggregato pu`o (anzi, `e la sua
caratteristica principale) avere una struttura anche molto profonda, con pi` u livelli
gerarchici e raggruppamenti in collezioni di vario genere (liste, insiemi, mappe, ecc.).
Quasi tutte le implementazioni permettono inoltre di inserire dei riferimenti ad altri
documenti rendendoli molto simili nel funzionamento ai cosiddetti database a oggetti.
Questo modo di trattare i dati `e molto comodo per gli sviluppatori, i quali possono
disporre di una base dati molto dinamica e agile, caratteristica di particolare aiuto
durante le frenetiche fasi di sviluppo di un nuovo progetto o di un prototipo per attirare
finanziatori4 .
Alcuni esempi di database document store sono: MongoDB[21], CouchDB[22], Couchstore[23]
e OrientDB[24].

Indici
Il grande vantaggio di questo modello `e che i documenti possono essere indicizzati, sia a
livello di singolo attributo che creando indici composti. Il fatto che questa funzionalit`
a
4`
E curioso notare come spesso i database a documenti vengano associati al concetto di startup e di
tecniche di project management della corrente Agile come Scrum, eXtreme Programming e Kanban.

10
2.1. Classificazione in base al modello dei dati

sia, nellutilizzo, molto simile alla controparte del mondo relazionale, non `e del tutto
casuale. Gli indici infatti sono praticamente sempre realizzati tramite B+tree, gli stessi
utilizzati nei database relazionali; ci`
o permette di avere le stesse possibilit`a:

ricerche di egualit`
a;

ordinamento e ricerche per intervalli (range queries);

indici su pi`
u attributi;

riferimenti ad altri documenti (operazione simile alla JOIN ).

Ruolo di Javascript e JSON


Di grande importanza per lo sviluppo e la diffusione dei database NoSQL, in particolare
per i Document store, `e stata la scelta di utilizzare il formato dei dati JSON [25] per
linterazione con le applicazioni, se non addirittura Javascript stesso5 come linguaggio di
programmazione allinterno del database (MongoDB [21], CouchDB [22]). Sia Javascript
che JSON sono particolarmente apprezzati dagli sviluppatori di web application inter-
attive (il cosiddetto Web 2.0 ); il formato JSON in particolare sta prendendo il posto di
XML nellambito dei web service, per svariati motivi:

sintassi pi`
u succinta rispetto a XML/SOAP;

semplicit`
a duso delle varie librerie, disponibili praticamente per qualsiasi linguag-
gio di programmazione (non solo Javascript);

minore formalit`
a nella definizione dei formati di interscambio dati;

possibilit`
a di invocare i web service direttamente da applicazioni Javascript che
risiedono nel browser dellutente, scavalcando il middleware.

Tutte queste caratteristiche per` o diminuiscono il controllo (schema dei dati) e la


prevedibilit`a (evoluzione del formato dei messaggi) dei servizi, rendendo JSON meno
appetibile in ambito enterprise e di integrazione di sistemi complessi o mission-critical,
dove XML/SOAP continua ad essere il protocollo pi` u utilizzato.
Un esempio di integrazione molto spinta `e Node.js[26], una piattaforma basata sul
motore Javascript V8 di Chrome[27], molto utilizzata accoppiata a Document store come
MongoDB o CouchDB. Il vantaggio di questa configurazione `e che, utilizzando Javascript
per tutto lo stack applicativo (dalle pagine web, alle chiamate AJAX, al database),
permette a piccoli team di lavorare efficacemente su tutte le parti dellapplicazione,
favorendo imprese agili e dinamiche.
Ecco un esempio di documento JSON relativo ad un ipotetico ordine per unappli-
cazione di e-commerce:
5
JSON `e un sottoinsieme molto ridotto di Javascript, limitato alla definizione di oggetti in modo
letterale.

11
2. Caratteristiche dei database NoSQL

{
"_id": "d3015931-98de-4308-abf0-09438d32cb2c",
"purchase_code": "akg-456-45-45645645",
"customer_id": 234532,
"ship_date": "2013-01-16",
"total": 345.89,
"paid": true,
"payment_date": "2013-01-12",
"currency": "EUR",
"items": [
{
"SKU": "ASDF-78997898789",
"name": "Headphones",
"price": 45.67,
"color": "white"
},
{
"SKU": "KKGH-098234432",
"name": "Tennis table",
"price": 300.22,
"color": "white",
"accessories": [
"tennis table bats",
"green net",
"surface polish"
]
}
]
}

Lesempio mette in evidenza vari aspetti:

semplicit`
a della sintassi, con un ristretto insieme di tipi (stringhe, numeri, booleani).
Persino le date sono inserite come stringhe6 ;
sintassi esplicita per gli array (liste ordinate);
la forma gerarchica esplicita, ovvero senza lutilizzo di foreign key ma integrando
direttamente (embedding) gli oggetti come figli;
`e comunque possibile utilizzare ID che si riferiscono ad altri documenti;
la forma `e molto libera da schema (schemaless), ovvero `e possibile aggiungere
qualsiasi attributo si ritenga necessario, eventualmente
6
molti Document store permettono lutilizzo di estensioni JSON proprietarie, vedi ad esempio come la
funzione Date() di MongoDB per linserimento di date

12
2.1. Classificazione in base al modello dei dati

Campi di applicazione
I Document Store sono molto apprezzati per la grandissima flessibilit`a, che permette di
ottenere modelli dei dati complessi senza penalizzare le performance. Per questo motivo
sono molto utilizzati per la realizzazione di siti web, e-commerce, gestione documentale,
web service, giochi multiplayer massivi.

2.1.5. Modello di dati a Grafo


Questo modello dei dati `e utilizzato per memorizzare strutture a grafo diretto e sta
acquisendo molta importanza grazie ai moltissimi ambiti di utilizzo.

Una struttura dati complessa


In figura2.4 abbiamo un grafo che illustra alcune relazioni possibili in un gruppo di
persone.

Figura 2.4.: Esempio di grafo

Abbiamo:

tre tipi di relazione:


knows: relazione di conoscenza;
lives in: relazione di localit`
a;
likes: relazione di preferenza;

tre tipi di entit`


a:

13
2. Caratteristiche dei database NoSQL

cose oggetto di preferenza (rappresentate da rettangoli);


persone (rettangoli con i bordi arrotondati);
citt`
a di residenza (esagoni);

Anche a partire da una configurazione semplice come questa emerge la notevole com-
plessit`
a delle strutture da memorizzare, nonche del loro potenziale di crescita esplosivo.

Gestione degli indici


Volendo memorizzare una struttura a grafo in un database relazionale o aggregate-
oriented `e necessario creare una struttura simile:

unentit`
a VERTICES per i vertici:
ID del vertice;
varie colonne per le informazioni contenute nel vertice (nome, ecc.);
unentit`
a EDGES per gli archi :
ID dellarco;
VERTEX FROM : ID del vertice di partenza;
VERTEX TO: ID del vertice di destinazione;
informazioni aggiuntive sulla relazione fra i due vertici.
indici aggiuntivi:
indice su EDGES.VERTEX FROM ;
indice su EDGES.VERTEX TO.

Ecco una possibile implementazione in SQL7 :

1 create table VERTICES (


2 ID integer primary key,
3 NAME varchar(16) not null
4 );
5

6 create table EDGES (


7 ID integer primary key,
8 NAME varchar(16) not null,
9 VERTEX_FROM integer not null references VERTICES(id),
10 VERTEX_TO integer not null references VERTICES(id)
11 );
12

13 create index VERTEX_FROM on EDGES(VERTEX_FROM);


14 create index VERTEX_TO on EDGES(VERTEX_TO);
7
Lesempio `e stato verificato con PostgreSQL

14
2.1. Classificazione in base al modello dei dati

Gli indici su EDGES.VERTEX FROM e EDGES.VERTEX TO (righe 13-14) sono


di fondamentale importanza per ottenere delle performance accettabili durante lesplo-
razione del grafo, e sono solitamente implementati tramite B-Tree, B+Tree o indici
Hash. Questo approccio per` o, benche corretto, risente di un grave problema: allau-
mentare delle righe (soprattutto sulla tabella dei vertici) il costo in lettura aumenta
sensibilmente.
La complessit` a di una lettura tramite indice B-Tree infatti `e dellordine di O(log(n)),
con n = numero totale di vertici del grafo. Per esaminare gli M archi in uscita dal
vertice di partenza abbiamo quindi un costo computazionale C di

C = O(M log(n))

Usare indici di tipo Hash in teoria potrebbe dare prestazioni migliori, perche sono pro-
gettati per avere una complessit` a (secondo lanalisi ammortizzata) di O(1) (costante),
inoltre sono da utilizzare solo per interrogazioni di egualit`a8 . Quindi, in teoria, potreb-
bero consentire di scorrere tutti gli M archi in uscita con un tempo O(M ). Purtroppo
per`o le prestazioni di queste strutture degradano allaumentare della quantit`a di dati
memorizzati, degenerando in strutture ad albero (o, peggio, lineari). Aumentando il
fattore aumentano anche le collisioni della funzione hash, ottenendo quindi le stesse
prestazioni dei B-Tree.
I Graph database offrono una soluzione diversa. Per ottenere un tempo di lettura
costante, ogni singolo vertice ha un indice degli archi in uscita, utilizzando la
tecnica denominata Index-free adjacency . Poiche il numero M di archi uscenti da
un vertice `e (solitamente) molto minore del numero totale di archi del grafo, utilizzare
questa struttura permette di scorrere tutti gli M archi in uscita da un vertice con un
tempo (sempre in analisi ammortizzata) di

C = O(M )
Ci`o significa che le dimensioni globali del database non influiscono pi` u sulle
prestazioni a livello locale, rendendo possibile lanalisi di grafi di dimensioni difficil-
mente gestibili con indici globali.

Campi di applicazione
I Graph database permettono di estrarre, in tempi ragionevoli e in maniera molto
elegante, dati di grandissimo valore:

classificazione tramite algoritmi di vicinanza e clustering;

analisi di flussi di vario genere: navigazione in siti web e in social network, ecologia,
urbanistica, ecc.

profilazione degli utenti e suggerimenti per amicizie o acquisti.


8
Nel nostro caso, si cerca la riga di EDGES con un certo valore di VERTEX FROM oppure
VERTEX TO

15
2. Caratteristiche dei database NoSQL

Per questo motivo sono sempre pi` u indispensabili quando si renda necessario unanalisi
delle relazioni fra i dati, pi`
u che i dati stessi.
Alcuni esempi di Graph Database:

OrientDB [24];

Neo4j [28].

2.2. Modelli di distribuzione, consistenza dei dati e CAP


Theorem
Quasi tutti i database NoSQL, a parziale eccezione dei Graph database, sono stati pro-
gettati sin dal principio per funzionare da subito in modalit`a distribuita, ovvero su pi`
u
server. Ci`o implica tutta una serie di vantaggi, ma anche di rinunce, come vedremo.

2.3. Modelli di distribuzione


2.3.1. Single Server
Questa modalit` a `e la pi`
u semplice, nonche la meno problematica. Con un solo server di
database infatti, gli unici problemi da risolvere sono relativi alla gestione dei conflitti in
lettura e scrittura fra i vari client.

2.3.2. Replicazione
La replicazione dei dati `e uno stratagemma utilizzato con diversi scopi.
Il primo `e che, distribuendo gli stessi dati su pi`u server, aumenta la disponibilit`a degli
stessi e laffidabilit`
a dellinsieme. Se un nodo cade, infatti, ci sono gli altri che possono
sostituirlo mentre viene riparato e rimesso online.
Il secondo scopo `e di migliorare le performance in lettura. Avere molti nodi con gli
stessi dati permette una parallelizzazione praticamente lineare delle letture, che possono
essere distribuite in modo del tutto trasparente ai client. Inoltre, sfruttando il principio di
localit`
a dei dati, `e possibile erogare i dati dal nodo pi`
u vicino al client che li ha richiesti,
migliorando tempi di risposta e velocit`a di trasferimento, alleggerendo al contempo il
traffico globale dellinfrastruttura.

2.3.3. Sharding
Questa modalit` a `e la pi`
u complessa, prevede infatti il partizionamento dei dati in base
a vari criteri sui vari nodi, mantenendo gli stessi vantaggi della replicazione (affidabilit`a,
prestazioni in lettura) e aggiungendone di nuovi.
Il principale vantaggio dello sharding `e che, per come `e utilizzato nei database aggregate-
oriented, ha un effetto positivo anche sulle scritture, oltre che sulle letture. I dati inviati

16
2.4. CAP Theorem

dai client infatti vengono scritti sul primo nodo disponibile, con tempi di risposta simili
alla modalit`a single server9 .

2.4. CAP Theorem


Questo teorema, proposto per la prima volta da Eric Brewer [29] nel 2000, afferma che
un sistema distribuito pu`
o fornire solo contemporaneamente solo due fra le seguenti
garanzie:

Consistency (Consistenza): tutti i nodi vedono gli stessi dati nello stesso momento;

Availability (Disponibilit`
a): il sistema risponde a tutte le richieste;

Partition tolerance (Tolleranza al Partizionamento): il sistema continua ad operare


anche se alcune sue parti rimangono isolate dalle altre in modo arbitrario (ovvero
se il grafo che rappresenta il sistema `e disconnesso).

In verit`a, poiche si sta trattando di sistemi distribuiti, `e praticamente impossibile


garantire un tolleranza completa al partizionamento, perche `e sempre possibile che il
collegamento fra due nodi venga meno. La scelta da compiere, dunque, si riduce a:

rinunciare alla consistenza in favore della disponibilit`a;

rinunciare alla disponibilit`


a in favore della consistenza.

Questa scelta, come osservato in [1], non `e binaria (tutto o niente), ma sono possibili
varie sfumature. E ` possibile rinunciare ad un po di consistenza per poter avere un
sistema sempre disponibile, ovvero che sia in grado di dare sempre una risposta (anche
se magari utilizzando dati non aggiornati), e viceversa.

2.5. Rilassamento
La strategia pi`
u utilizzata dai database NoSQL `e tutto il contrario di quanto fatto dai
database relazionali finora, ovvero viene proposto un rilassamento dei requisiti ACID:
Atomicity, Consistency, Isolation, e Durability (Atomicit`a, Consistenza, Isolamento e
Durabilit`a). Vediamo in dettaglio come viene applicato questo rilassamento.

2.5.1. Rilassamento di Atomicit`


a e Isolamento
Uno degli argomenti pi` u forti contro i database NoSQL `e il limitato supporto alle
transazioni, praticamente tutti i database di tipo aggregate-oriented infatti le gestis-
cono solamente a livello di singolo aggregato: singolo dato nel caso dei Key-Value o
dei Column-Family store, documento nei Document store. Questa rinuncia, molto forte
e molto criticata, `e ovviamente dettata dalla necessit`a di avere tempi di risposta molto
9
Vedremo come ci`
o sia possibile nel paragrafo dedicato alla cosiddetta Eventual Consistency (2.5.3)

17
2. Caratteristiche dei database NoSQL

minori e aumentare la parallelizzabilit`a del sistema. Ci sono per`o alcune considerazioni


da fare in difesa di questa scelta, vediamone alcune.
In questi anni abbiamo visto grosse compagnie (soprattutto colossi delle-commerce
come Amazon e eBay) implementare sistemi di dimensioni ragguardevoli, distribuiti ge-
ograficamente, integrati con molti servizi esterni10 e con requisiti di performance molto
stringenti, soprattutto per quanto riguarda i tempi di risposta. Uno dei maggiori proble-
mi da risolvere infatti in un e-commerce `e che le pagine web del negozio devono essere
caricate sempre molto in fretta, non solo durante lo sfoglio dei cataloghi ma anche nelle
fasi di checkout (pagamento) e amministrative (registrazione utenti, backoffice), pena
la perdita di ordini e (letteralmente) milioni di euro di fatturato. Tutti questi requisiti
sono evidentemente in contrasto fra di loro; `e impensabile infatti poter fornire tempi di
risposta molto veloci se per completare una richiesta `e necessario orchestrare il lavoro di
cos` tanti attori. C`e poi un aspetto tecnico-economico molto importante da consider-
are, ovvero che limplementazione di transazioni distribuite su sistemi cos` numerosi ed
eterogenei `e, quando possibile, molto complicata, dai lunghi tempi di realizzazione e, in
definitiva, molto costosa.
Queste compagnie hanno deciso quindi di abbandonare il design monolitico per
abbracciare una filosofia meno stringente sui requisiti di transazionalit`a; ci`o si traduce
in sistemi asincroni, molto reattivi e in grado di sopportare eventuali inconsistenze dei
dati. Ci sono infatti molti ambiti dove ricevere dati non aggiornati o sporchi, ma molto
in fretta, costa meno che implementare un sistema transazionale completamente ACID-
compliant. Alcuni esempi:

aree dove `e tollerabile avere dati non aggiornati:


cataloghi;
statistiche: n. di clic, volume degli acquisti, performance del sistema, ecc.
immagini, testi e contenuti editoriali in generale di siti web;

aree che tollerano dati non consistenti:


carrelli della spesa: al momento del checkout, lutente ha la possibilit`
a di
ricontrollare e confermare il contenuto dellordine;
ancora una volta, contenuti editoriali: la propagazione delle modifiche (cor-
rezione errori, migliorie estetiche, ecc.) tollera qualche inconsistenza;
raccolta dati di monitoring: la fase di aggregazione di questi dati, necessaria
per la valorizzazione degli stessi, in un certo senso `e in grado di livellare
queste inconsistenze.

Comunque, anche senza andare a scomodare questi giganti, abbiamo molti esempi pi` u
semplici di questo rilassamento, vicini alla vita di tutti i giorni. Da molti anni infatti
10
fra questi ci possono essere vari tipi di database (cataloghi, dati di magazzino, profilazione utente,
tracciamento consegne, ecc.), sistemi di pagamento, salvataggio di dati di log, audit e monitoring,
ecc.

18
2.5. Rilassamento

la maggior parte dei siti web e dei blog sono basati su CMS (Content Management
System) che utilizzano MySQL con motore MyISAM che, grazie al basso costo e alle
alte performance in lettura, ha avuto un enorme e duraturo successo. Questa velocit`a
per`o `e frutto di rinunce simili (se non maggiori) a quelle che abbiamo gi`a visto per i
database aggregate oriented:

assenza di transazioni (al massimo si pu`o eseguire un table lock );

assenza di chiavi esterne (foreign key).

2.5.2. Rilassamento della Durabilit`


a
Lesempio pi` u estremo di rilassamento della durabili`a `e fornito da alcuni Key-Value
store, come abbiamo gi` a visto in 2.1.2. Spesso infatti vengono utilizzati solamente come
storage in memoria primaria (RAM)11 , potendo quindi fornire altissime performance
in lettura e scrittura, a discapito dellaffidabilit`a: se il processo viene terminato, tutti
i dati vengono persi. In molti casi `e possibile configurarli in modo che eseguano un
flush (scaricamento su disco) dei dati periodico (ad esempio Redis[9] in modalit`a RDB);
questa operazione per` o pu`o avere un costo molto elevato, perche blocca in scrittura tutte
le strutture coinvolte.
` ovviamente possibile ottenere una via di mezzo, ovvero garantire la durabilit`a entro
E
un certo lasso di tempo, durante il quale il sistema si preoccupa di salvare in maniera
permanente le modifiche. In questo caso si parla di finestra di inconsistenza; maggiore
`e questa finestra, maggiore `e il rischio di perdere dati in seguito ad un crash.

2.5.3. Eventual Consistency


Questa espressione, la cui poco felice traduzione in italiano potrebbe essere consistenza
in qualche istante futuro, descrive in modo molto sintetico la modalit`a con cui viene
gestita questa garanzia:

il sistema risponde subito alle richieste dei client;

le modifiche ai dati si propagano in maniera asincrona fra i vari nodi;

ad un certo punto, quando tutti i nodi avranno ricevuto gli aggiornamenti, la


consistenza degli stessi sar`
a garantita, ma non prima.

Particolarit`
a dei Graph database
Quasi tutti i Graph database, in controtendenza rispetto ai database aggregate-
oriented, implementano le transazioni e le propriet` a ACID, per questo sono
11
Anche molti database relazionali, come ad esempio MySql, forniscono questa possibilit`
a, ma
solitamente pongono grosse limitazioni, che riportano il tutto a NoSQL

19
2. Caratteristiche dei database NoSQL

considerati una categoria a parte nel mondo NoSQL. Ovviamente ogni prodotto for-
nisce diverse garanzie, ma purtroppo le grandi differenze con il modello relazionale non
permettono un confronto diretto sui livelli di isolamento ANSI/ISO SQL standard.
Un altro aspetto peculiare `e che `e molto difficile poter utilizzare lo sharding, data la
natura estremamente connessa dei dati in essi contenuti. La pi` u grande distinzione
fra aggregate-oriented e graph-oriented potrebbe infatti essere la seguente:

aggregate-oriented: molti dati, raggruppati in aggregati con pochi o nessun


collegamento fra di loro;

graph-oriented: pochi nodi, estremamente connessi con relazioni dinamiche.

2.5.4. Perch
e il rilassamento
` dunque possibile tollerare sistemi che non garantiscono le propriet`a ACID? La risposta,
E
come molto spesso accade, `e dipende.
Ci sono sistemi che, a seguito di inconsistenze, possono produrre immensi danni eco-
nomici o fisici; il pensiero va subito ai mainframe delle banche, ma anche ai sistemi
di controllo di impianti energetici, industriali, ospedalieri. In questo caso la soluzione
migliore rimane ancora investire in complessi application server in grado di coordinare
transazioni distribuite, hardware potente e infrastrutture ad hoc, con costi molto alti.
Ci sono per` o anche molti altri ambiti in cui una piccola percentuale di inconsistenze
si pu`o non solo tollerare, ma addirittura ignorare o riparare con un costo minore rispet-
to al danno subito, in ogni caso minore del costo di avere una soluzione corretta
al 100%. Tramite apposite tecniche di programmazione `e possibile implementare fun-
zionalit`a idempotenti, o comunque in grado di riparare gli errori o mitigarne gli effetti
sui dati, spesso in maniera trasparente agli utilizzatori. In questo modo `e anche possi-
bile slegarsi da blasonati prodotti commerciali di fascia alta, spesso sovradimensionati
rispetto alleffettivo utilizzo.
Infine si vuole far notare come i database NoSQL, nonostante laria di novit` a e
innovazione che li circonda, sfruttino i medesimi algoritmi e tecnologie inventate
e perfezionate dai database relazionali. La grossa la differenza sta nel come questi
strumenti vengono utilizzati, a volte in modi davvero nuovi e originali.

20
3. Bibliografia
[1] Pramod J. Sadalage, Martin Fowler (2012) NoSQL Distilled: a brief guide to the
emerging world of polyglot persitence. Addison-Wesley / Pearson Education.

[2] Eric Evans (2004) Domain-Driven Design. Addison-Wesley.

[3] David A. Patterson, John L. Hennessy (1995). Struttura e progetto dei calcolatori
- Linterfaccia hardware software. Zanichelli.

[4] PostgreSQL (version 9.2) - Hstore. http://www.postgresql.org/docs/9.2/


static/hstore.html

[5] DB2 NoSQL Support. http://www-01.ibm.com/software/data/db2/linux-unix-


windows/nosql-support.html

[6] Oracle XML DB. http://www.oracle.com/technetwork/database-


features/xmldb/overview/index.html

[7] EHCache. http://ehcache.org/

[8] Memcached. http://memcached.org/

[9] Redis key-value store. http://redis.io/

[10] Amazon SimpleDB. http://aws.amazon.com/simpledb/

[11] Berkley DB. http://www.oracle.com/technetwork/products/berkeleydb/overview/index.html

[12] MemcacheDB. http://memcachedb.org/

[13] Riak. http://docs.basho.com/riak/latest/

[14] Secondary Indexes in Riak. http://basho.com/secondary-indexes-in-riak/

[15] Rusty Klophaus (2011). Querying Riak Just Got Easier - Introducing Secondary In-
dices (presentazione) http://www.slideshare.net/rklophaus/querying-riak-just-got-
easier-introducing-secondary-indices

[16] Apache Hadoop. http://hadoop.apache.org/

[17] Articolo Wikipedia su MapReduce, con link sullargomento.


http://it.wikipedia.org/wiki/MapReduce

[18] Cassandra. http://cassandra.apache.org/

21
3. Bibliografia

[19] HBase. http://hbase.apache.org/

[20] Jeff Dean (2005) BigTable: A Distributed Structured Storage System.


https://www.cs.washington.edu/htbin-post/mvis/mvis?ID=437

[21] MongoDB. http://www.mongodb.org/

[22] CouchDB. http://couchdb.apache.org/

[23] Couchbase. http://www.couchbase.com/

[24] OrientDB. http://www.orientdb.org/

[25] JSON. http://www.json.org/

[26] Node.js http://nodejs.org/

[27] Chrome V8. http://code.google.com/p/v8/

[28] Neo4j. http://www.neo4j.org/

[29] Eric A. Brewer (2000), Towards robust distributed systems.


http://www.cs.berkeley.edu/ brewer/papers/

22