Guida galattica ai NoSQL

G

Nel precedente articolo abbiamo visto a grandi linee le differenze sostanziali tra SQL e NoSQL, tuttavia NoSQL di per sé è un mondo sconfinato.
I vari motori NoSQL si differenziano soprattutto per il modo in cui immagazzinano i dati e, conseguentemente, come li presentano all’utente.

I tipi più comuni di NoSQL sono sostanzialmente 4:

  • Orientati alle colonne (column-oriented)
  • Orientati ai documenti (Document Store)
  • A coppie chiave-valore (Key Value Store)
  • A grafo (Graph)

Orientati alle colonne

Come il nome stesso ci suggerisce, a differenza dei classici database relazionali, in questo tipo di database l’informazione è salvata per colonna.
Prendiamo come esempio la tabella:

AutoreID Nome Cognome
42 Nico Caprioli
666 Andrea Simone Costa
8080 Dario Frongillo

Trascurando eventuali ottimizzazioni, in un clasico database relazionale i dati verrebbero serializzati come:

42;Nico;Caprioli
666;Andra Simone;Costa
8080;Dario;Frongillo

Nei database orientati alle colonne invece si avrebbe:

42;666;8080
Nico;Andrea Simone;Dario
Caprioli;Costa;Frongillo

Questo modo di gestire i dati porta vantaggi nel caso di tabelle il cui numero di colonne varia nel tempo, permettendo una modellazione banale di nuove specifiche non previste nel progetto iniziale.
In particolare questo tipo di database trova largo utilizzo in sistemi OLAP, dove utilizzare un sottoinsieme delle colonne è pane quotidiano.
Infine una nota di merito va a quelle funzioni come il calcolo del minimo o del massimo: dal momento che i dati sono immagazinati per colonne, l’aumento di performance è notevole.
Tra i maggiori esponenti di questa tipologia di database troviamo:

  • Apache Cassandra
  • Apache HBase
  • Google BigTable

Orientati ai documenti

In questa categoria rientrano i database che permettono la manipolazione di dati semi-strutturati.
In genere questi database usano una rappresentazione interna che può variare tra XML, JSON, BSON o YAML e in genere forniscono un accesso tramite REST API o con protocolli di interoperabilità tra linguaggi come Apache Thrift o gRPC.
Volendo fare un confronto con i database relazionali, possiamo affermare che un documento corrisponde ad una riga; tuttavia questo documento, a differenza della riga, può non avere uno schema preciso. Riprendendo l’esempio precedente, potremmo avere una situazione del genere:

{
  id: 42,
  nome: "Nico",
  cognome: "Caprioli",
  autore_di_questo_articolo: true
},
{
  id: 666,
  nome: "Andrea Simone",
  cognome: "Costa"
}

L’esempio è decisamente idiota, ma rende chiaro un concetto: sebbene i due documenti si assomiglino, uno porta un valore aggiunto rispetto all’altro.
Nel secondo caso, venendo da una tradizione SQL, si potrebbe pensare che autore_di_questo_articolo sia un valore nullo. In realtà tale valore non esiste affatto, non è allocato in memoria spazio per contenerlo. Per chiunque sia minimamente familiare con JSON, il prossimo passo dei database orientati ai documenti è banale: il tipo di dato di un elemento all’interno del documento, a differenza di SQL non deve necessariamente essere un tipo primitivo. È piuttosto comune difatti ritrovarsi con elementi che sono oggetti o liste, a loro volta contenenti altri oggetti e così via. La nidificazione è possibile con questi tipo di database e ne rappresenta uno dei punti di forza maggiore, in quanto permette una flessibilità inarrivabile da SQL. È importante notare che, sebbene questi database siano senza schema, è possibile definire degli indici. Tra i maggiori esponenti di questa tipologia di database troviamo:

  • BaseX
  • MongoDB
  • CouchDB

Coppie chiave-valore

I database di tipo chiave-valore sono particolarmente affini a quelli orientati ai documenti, infatti come questi ultimi non richiedono l’esistenza di uno schema e allo stesso modo, si associa a una data chiave, un determinato valore.
La differenza sostanziale tra i database chiave-valore e quelli orientati ai documenti risiede nel modo in cui le chiavi vengono gestite, infatti si hanno due punti in cui le due soluzioni divergono:

  • La chiave deve sempre essere specificata
  • I valori associati ad una chiave non possono essere indicizzati né è possibile interrogarli, pertanto sono opachi dal punto di vista del database

Volendo fare un paragone con le strutture dati tipiche di un qualsiasi linguaggio di programmazione, si potrebbe dire che i database di tipo chiave-valore sono equivalenti ad una Hash Table.
Date le restrizioni poste in essere sulle chiavi e sull’opacità dei valori, è evidente che questi database siano ottimizzati per l’interrogazioni sulle chiavi. Non è raro infatti trovarsi in situazioni in cui le chiavi siano generate in modo intelligente, ad esempio tramite un UUID, utilizzando poi il database come cache.
Dal momento che questi database tendono ad essere in-memory per avere le migliori performance possibili, non è strano scoprire che sono in grado di rispondere a decine di migliaia di richieste al secondo[1]. È di dovere precisare che, sebbene i valori siano opachi, alcuni database forniscono un meccanismo per identificare il tipo di dato ed operarci di conseguenza. Alcuni tipi di dati potrebbero essere, oltre ai classici scalari, stringhe, set (sia ordinati che non ordinati) o liste.Ritornando al nostro classico esempio:

42: "Nico Caprioli"
666: ["Andrea Simone Costa", "non sa il JS"]

Tra i più popolari troviamo:

    • Redis
    • Memcached
    • Voldemort

Grafi

Come suggerisce il nome, nei database a grafo le entità sono rappresentate da nodi di un grafo, collegati tra loro tramite relazioni.
Questi tipi di database trovano piena utilità in quei contesti in cui la relazione tra entità è il dato importante e porta con sé informazioni, come ad esempio relazioni sociali tra persone, trasporti o topologie di rete. Vien da sé che questi tipi di database hanno un contesto applicativo piuttosto ristretto e facilmente identificabile in fase di design, non è tuttavia raro che i dati di per sé vengano memorizzati in un database orientato ai documenti, utilizzando il grafo solo per rappresentare le relazioni.Sì capisce che l’esempio presentato fino ad ora non è applicabile in questo caso, però una valida alternativa per vedere visivamente come siano rappresentati i dati è comunque utile:

Tali database infatti forniscono operazioni native per interrogare i grafi come shortest path, o nodi ad una certa distanza dal nodo corrente. I database di questo tipo sono abbastanza rari; le soluzioni attuali sono:

    • Neo4j
    • FlockDB

Conclusioni

A questo punto, una tabella riassuntiva non può che essere comoda per la scelta del NoSQL che meglio si adatta ai propri scopi:

Proprietà Orientato alle colonne Orientato ai documenti Coppie chiave-valore A grafo
Supporto per uno schema simil-tabulare No No
Update Parziale No
Query sul singolo valore No
Funzioni di aggregazione tra righe No No No
Relazioni tra entità No No No
Batch Update No

A proposito di me

Nico Caprioli

Si diletta con i computer sin dall'età di 8 anni, per sbarcare nel mondo della programmazione durante il liceo.
Dopo una laurea magistrale in Ingegneria Informatica, passa le sue giornate a battere i tasti sperando di scrivere codice C# valido.

Di Nico Caprioli

Gli articoli più letti

Articoli recenti

Commenti recenti