2.1 Apariția termenului NoSQL

Recent, termenul „NoSQL” a devenit foarte la modă și popular, tot felul de soluții software sunt dezvoltate și promovate în mod activ sub acest semn. NoSQL a devenit sinonim cu cantități uriașe de date, scalabilitate liniară, clustere, toleranță la erori, non-relaționalitate. Cu toate acestea, puțini oameni au o înțelegere clară a ceea ce este stocarea NoSQL, cum a apărut termenul și ce caracteristici comune au. Să încercăm să umplem acest gol.

Cel mai interesant lucru despre termen este că, în ciuda faptului că a fost folosit pentru prima dată la sfârșitul anilor 90, a căpătat un sens real în forma în care este folosit acum doar la mijlocul anului 2009. Inițial, acesta a fost numele unui -bază de date sursă creată de Carlo Strozzi, care a stocat toate datele ca fișiere ASCII și a folosit scripturi shell în loc de SQL pentru a accesa datele. Nu avea nimic de-a face cu „NoSQL” în forma sa actuală.

În iunie 2009, Johan Oskarsson a organizat o întâlnire la San Francisco pentru a discuta noile tendințe din piața de stocare și procesare IT. Principalul impuls al întâlnirii l-au fost noile produse open source precum BigTable și Dynamo. Pentru un semn luminos pentru o întâlnire, a fost necesar să se găsească un termen încăpător și concis care să se potrivească perfect în hashtag-ul Twitter. Unul dintre acești termeni a fost propus de Eric Evans de la RackSpace - „NoSQL”. Termenul a fost planificat pentru o singură întâlnire și nu a avut o încărcătură semantică profundă, dar s-a întâmplat să se răspândească în rețeaua globală ca o reclamă virală și să devină numele de facto al unei întregi direcții din industria IT. Apropo, la conferință au vorbit Voldemort (clona Amazon Dynamo), Cassandra, Hbase (analogii Google BigTable), Hypertable, CouchDB, MongoDB.

Merită să subliniem încă o dată că termenul „NoSQL” este de origine complet spontană și nu are în spate o definiție general acceptată sau o instituție științifică. Acest nume caracterizează mai degrabă vectorul dezvoltării IT departe de bazele de date relaționale. Aceasta înseamnă Not Only SQL, deși există susținători ai definiției directe a No SQL. Pramod Sadalaj și Martin Fowler au încercat să grupeze și să sistematizeze cunoștințele despre lumea NoSQL în recenta lor carte „NoSQL Distilled”.

2.2 Caracteristicile de bază ale bazelor de date NoSQL

Există puține caracteristici comune pentru toate NoSQL, deoarece multe sisteme eterogene sunt acum ascunse sub eticheta NoSQL (probabil cea mai completă listă poate fi găsită la http://nosql-database.org/). Multe caracteristici sunt specifice doar anumitor baze de date NoSQL, cu siguranță voi menționa acest lucru atunci când voi enumera.

1. Nu se utilizează SQL

Mă refer la ANSI SQL DML, deoarece multe baze de date încearcă să folosească limbaje de interogare similare cu binecunoscuta sintaxă preferată, dar nimeni nu a reușit să o implementeze pe deplin și este puțin probabil să reușească. Deși există zvonuri startup-uri care încearcă să implementeze SQL, de exemplu în hadup ( http://www.drawntoscalehq.com/ și http://www.hadapt.com/ ).

2. Nestructurat (fără schemă)

Semnificația este că în bazele de date NoSQL, spre deosebire de bazele de date relaționale, structura datelor nu este reglementată (sau slab tipizată, dacă tragem analogii cu limbaje de programare) - puteți adăuga un câmp arbitrar într-o linie sau document separat fără a modifica mai întâi structura declarativă. a întregului tabel. Astfel, dacă este nevoie să se schimbe modelul de date, atunci singura acțiune suficientă este să reflecte modificarea codului aplicației.

De exemplu, la redenumirea unui câmp în 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"

Dacă schimbăm logica aplicației, atunci ne așteptăm la un câmp nou și la citire. Dar din cauza lipsei unei scheme de date, câmpul totalSum lipsește din alte obiecte Order deja existente. În această situație, există două opțiuni pentru acțiuni ulterioare.

Primul este să accesați cu crawlere toate documentele și să actualizați acest câmp în toate documentele existente. Datorită volumului de date, acest proces are loc fără blocări (comparabil cu comanda alter table rename column), astfel încât în ​​timpul actualizării, datele deja existente pot fi citite de alte procese. Prin urmare, a doua opțiune - verificarea codului aplicației - este inevitabilă:

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

Și deja când vom reînregistra, vom scrie acest câmp în baza de date într-un nou format.

O consecință plăcută a absenței unei scheme este eficiența lucrului cu date rare. Dacă un document are un câmp date_published, iar cel de-al doilea nu, atunci nu va fi creat niciun câmp gol date_published pentru al doilea. Acest lucru, în principiu, este logic, dar un exemplu mai puțin evident sunt bazele de date NoSQL din familia de coloane, care utilizează conceptele familiare de tabele / coloane. Cu toate acestea, din cauza lipsei unei scheme, coloanele nu sunt declarate declarativ și pot fi modificate/adăugate în timpul sesiunii de bază de date a unui utilizator. Acest lucru permite, în special, utilizarea coloanelor dinamice pentru implementarea listelor.

Schema nestructurată are dezavantajele sale - pe lângă supraîncărcarea menționată mai sus în codul aplicației la schimbarea modelului de date - absența a tot felul de restricții de la bază (nu nulă, unică, constrângere de verificare etc.), plus că există sunt dificultăți suplimentare în înțelegerea și controlul datelor de structură atunci când se lucrează cu baza de date a diferitelor proiecte în paralel (nu există dicționare pe partea bazei de date). Cu toate acestea, într-o lume modernă în schimbare rapidă, o astfel de flexibilitate este încă un avantaj. Un exemplu este Twitter, care acum cinci ani, împreună cu tweet-ul, stoca doar puține informații suplimentare (ora, mânerul Twitter și încă câțiva octeți de metainformații), dar acum, pe lângă mesajul în sine, încă câțiva. kilobytes de metadate sunt stocați în baza de date.

(În continuare, vorbim în principal despre baze de date cheie-valoare, documente și familii de coloane, bazele de date grafice pot să nu aibă aceste proprietăți)

2.3. Reprezentarea datelor sub formă de agregate (agregate)

Spre deosebire de modelul relațional, care stochează entitatea logică de afaceri a aplicației în diferite tabele fizice în scopuri de normalizare, magazinele NoSQL operează pe aceste entități ca obiecte holistice:

Acest exemplu demonstrează agregările pentru un model relațional conceptual standard de comerț electronic „Comandă - Articole de comandă - Plăți - Produs”. În ambele cazuri, comanda este combinată cu poziții într-un singur obiect logic, în timp ce fiecare poziție stochează un link către produs și unele dintre atributele acestuia, de exemplu, numele (o astfel de denormalizare este necesară pentru a nu solicita un obiect produs la preluare). o ordine – regula principală a sistemelor distribuite este „uniunea” între obiecte). Într-un agregat, plățile sunt combinate cu comanda și sunt parte integrantă a obiectului, în celălalt sunt plasate într-un obiect separat. Aceasta demonstrează regula principală pentru proiectarea unei structuri de date în bazele de date NoSQL - trebuie să se supună cerințelor aplicației și să fie optimizată pe cât posibil pentru cele mai frecvente solicitări.

Mulți vor obiecta, observând că lucrul cu obiecte mari, adesea denormalizate, este plin de numeroase probleme atunci când se încearcă interogări arbitrare asupra datelor atunci când interogările nu se încadrează în structura agregatelor. Ce se întâmplă dacă folosim comenzi împreună cu elementele rând de comandă și plăți (așa funcționează aplicația), dar compania ne cere să numărăm câte unități dintr-un anumit produs au fost vândute luna trecută? În acest caz, în loc să scanăm tabelul OrderItem (în cazul unui model relațional), va trebui să recuperăm toate comenzile în stocarea NoSQL, deși nu vom avea nevoie de multe din aceste informații. Din păcate, acesta este un compromis care trebuie făcut într-un sistem distribuit: nu putem normaliza datele ca într-un sistem convențional cu un singur server,

Am încercat să grupez avantajele și dezavantajele ambelor abordări într-un tabel: