2.1 Nascita del termine NoSQL

Recentemente, il termine "NoSQL" è diventato molto di moda e popolare, tutti i tipi di soluzioni software vengono attivamente sviluppati e promossi sotto questo segno. NoSQL è diventato sinonimo di enormi quantità di dati, scalabilità lineare, cluster, tolleranza agli errori, non relazionalità. Tuttavia, poche persone hanno una chiara comprensione di cosa sia l'archiviazione NoSQL, come è apparso il termine e quali caratteristiche comuni hanno. Proviamo a colmare questa lacuna.

La cosa più interessante del termine è che nonostante sia stato utilizzato per la prima volta alla fine degli anni '90, ha acquisito un significato reale solo nella forma in cui viene utilizzato ora a metà del 2009. Inizialmente, questo era il nome di un aperto -source database creato da Carlo Strozzi, che memorizzava tutti i dati come file ASCII e utilizzava script di shell invece di SQL per accedere ai dati. Non aveva nulla a che fare con "NoSQL" nella sua forma attuale.

Nel giugno 2009 Johan Oskarsson ha organizzato un incontro a San Francisco per discutere le nuove tendenze nel mercato dell'archiviazione e dell'elaborazione IT. L'impulso principale per l'incontro sono stati i nuovi prodotti open source come BigTable e Dynamo. Per un segno luminoso per un incontro, era necessario trovare un termine capiente e conciso che si adattasse perfettamente all'hashtag di Twitter. Uno di questi termini è stato proposto da Eric Evans di RackSpace - "NoSQL". Il termine era previsto per un solo incontro e non aveva un profondo carico semantico, ma è successo che si è diffuso in tutta la rete globale come una pubblicità virale ed è diventato di fatto il nome di un'intera tendenza nel settore IT. A proposito, alla conferenza hanno parlato Voldemort (clone di Amazon Dynamo), Cassandra, Hbase (analoghi di Google BigTable), Hypertable, CouchDB, MongoDB.

Vale la pena sottolineare ancora una volta che il termine "NoSQL" è di origine completamente spontanea e non ha dietro una definizione generalmente accettata o un'istituzione scientifica. Questo nome caratterizza piuttosto il vettore dello sviluppo IT lontano dai database relazionali. Sta per Not Only SQL, anche se ci sono sostenitori della definizione diretta di No SQL. Pramod Sadalaj e Martin Fowler hanno cercato di raggruppare e sistematizzare la conoscenza del mondo NoSQL nel loro recente libro "NoSQL Distilled".

2.2 Caratteristiche di base dei database NoSQL

Ci sono poche caratteristiche comuni per tutti i NoSQL, dal momento che molti sistemi eterogenei sono ora nascosti sotto l'etichetta NoSQL (forse l'elenco più completo può essere trovato su http://nosql-database.org/). Molte caratteristiche sono peculiari solo di alcuni database NoSQL, lo menzionerò sicuramente durante l'elenco.

1. Non viene utilizzato SQL

Intendo ANSI SQL DML, poiché molti database cercano di utilizzare linguaggi di query simili alla nota sintassi preferita, ma nessuno è riuscito a implementarlo completamente ed è improbabile che abbia successo. Anche se si dice che startup stiano tentando di implementare SQL, ad esempio in hadup ( http://www.drawntoscalehq.com/ e http://www.hadapt.com/ ).

2. Non strutturato (senza schema)

Il significato è che nei database NoSQL, a differenza dei database relazionali, la struttura dei dati non è regolamentata (o debolmente tipizzata, se tracciamo analogie con i linguaggi di programmazione): puoi aggiungere un campo arbitrario in una riga o documento separato senza prima modificare in modo dichiarativo la struttura dell'intera tavolata. Pertanto, se è necessario modificare il modello di dati, l'unica azione sufficiente è riflettere la modifica nel codice dell'applicazione.

Ad esempio, quando si rinomina un campo in MongoDB:

BasicDBObject order = new BasicDBObject();
order.put("date", orderDate); // this field was a long time ago
order.put("totalSum", total); // before we just used "sum"

Se cambiamo la logica dell'applicazione, allora ci aspettiamo un nuovo campo anche durante la lettura. Ma a causa della mancanza di uno schema di dati, il campo totalSum non è presente in altri oggetti Order già esistenti. In questa situazione, ci sono due opzioni per ulteriori azioni.

Il primo è eseguire la scansione di tutti i documenti e aggiornare questo campo in tutti i documenti esistenti. A causa del volume di dati, questo processo avviene senza alcun blocco (paragonabile al comando alter table rename column), quindi durante l'aggiornamento, i dati già esistenti possono essere letti da altri processi. Pertanto, la seconda opzione, il controllo del codice dell'applicazione, è inevitabile:

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble("sum"); // This is the old model
if (totalSum  == null)
totalSum = order.getDouble("totalSum"); // This is the updated model

E già quando registreremo nuovamente, scriveremo questo campo nel database in un nuovo formato.

Una piacevole conseguenza dell'assenza di uno schema è l'efficienza nel lavorare con dati sparsi. Se un documento ha un campo data_pubblicato e il secondo no, per il secondo non verrà creato alcun campo vuoto data_pubblicato. Questo, in linea di principio, è logico, ma un esempio meno ovvio sono i database NoSQL della famiglia di colonne, che utilizzano i concetti familiari di tabelle/colonne. Tuttavia, a causa della mancanza di uno schema, le colonne non vengono dichiarate in modo dichiarativo e possono essere modificate/aggiunte durante la sessione del database di un utente. Ciò consente, in particolare, l'utilizzo di colonne dinamiche per l'implementazione di liste.

Lo schema non strutturato ha i suoi svantaggi - oltre al suddetto sovraccarico nel codice dell'applicazione quando si cambia il modello di dati - l'assenza di tutti i tipi di restrizioni dalla base (non nullo, univoco, vincolo di controllo, ecc.), In più lì sono ulteriori difficoltà nella comprensione e nel controllo dei dati della struttura quando si lavora con il database di diversi progetti in parallelo (non ci sono dizionari sul lato del database). Tuttavia, in un mondo moderno in rapida evoluzione, tale flessibilità è ancora un vantaggio. Un esempio è Twitter, che cinque anni fa, insieme al tweet, memorizzava solo poche informazioni aggiuntive (ora, handle di Twitter e qualche byte di metainformazione in più), ma ora, oltre al messaggio stesso, qualche informazione in più kilobyte di metadati sono memorizzati nel database.

(D'ora in poi, si parlerà principalmente di database di valori-chiave, documenti e famiglie di colonne, i database a grafo potrebbero non avere queste proprietà)

2.3. Rappresentazione dei dati sotto forma di aggregati (aggregati)

A differenza del modello relazionale, che memorizza l'entità aziendale logica dell'applicazione in varie tabelle fisiche per scopi di normalizzazione, gli archivi NoSQL operano su queste entità come oggetti olistici:

Questo esempio mostra le aggregazioni per un modello relazionale concettuale di e-commerce standard "Ordine - Articoli dell'ordine - Pagamenti - Prodotto". In entrambi i casi, l'ordine è combinato con le posizioni in un oggetto logico, mentre ogni posizione memorizza un collegamento al prodotto e alcuni dei suoi attributi, ad esempio il nome (tale denormalizzazione è necessaria per non richiedere un oggetto prodotto durante il recupero un ordine - la regola principale dei sistemi distribuiti è "join" tra oggetti). In un aggregato, i pagamenti sono combinati con l'ordine e sono parte integrante dell'oggetto, nell'altro sono inseriti in un oggetto separato. Ciò dimostra la regola principale per progettare una struttura dati nei database NoSQL: deve rispettare i requisiti dell'applicazione ed essere ottimizzata il più possibile per le richieste più frequenti.

Molti obietteranno, osservando che lavorare con oggetti di grandi dimensioni, spesso denormalizzati, è irto di numerosi problemi quando si provano query arbitrarie sui dati quando le query non si adattano alla struttura degli aggregati. Cosa succede se utilizziamo gli ordini insieme alle voci dell'ordine e ai pagamenti (è così che funziona l'app), ma l'azienda ci chiede di contare quante unità di un particolare prodotto sono state vendute il mese scorso? In questo caso, invece di scansionare la tabella OrderItem (nel caso di un modello relazionale), dovremo recuperare tutti gli ordini nello storage NoSQL, anche se non avremo bisogno di molte di queste informazioni. Sfortunatamente, questo è un compromesso che deve essere fatto in un sistema distribuito: non possiamo normalizzare i dati come in un sistema convenzionale a server singolo,

Ho provato a raggruppare i pro e i contro di entrambi gli approcci in una tabella: