2.1 Uppkomsten av termen NoSQL

Nyligen har termen "NoSQL" blivit mycket fashionabel och populär, alla typer av mjukvarulösningar utvecklas och marknadsförs aktivt under detta tecken. NoSQL har blivit synonymt med enorma mängder data, linjär skalbarhet, kluster, feltolerans, icke-relationalitet. Det är dock få som har en klar förståelse för vad NoSQL-lagring är, hur termen såg ut och vilka gemensamma egenskaper de har. Låt oss försöka fylla denna lucka.

Det mest intressanta med begreppet är att trots att det först användes i slutet av 90-talet fick det verklig betydelse först i den form som det används i nu i mitten av 2009. Till en början var detta namnet på en öppen -källdatabas skapad av Carlo Strozzi, som lagrade all data som ASCII-filer och använde skalskript istället för SQL för att komma åt data. Det hade ingenting att göra med "NoSQL" i sin nuvarande form.

I juni 2009 anordnade Johan Oskarsson ett möte i San Francisco för att diskutera nya trender inom IT-lagrings- och processmarknaden. Den främsta drivkraften för mötet var nya produkter med öppen källkod som BigTable och Dynamo. För ett ljust tecken för ett möte var det nödvändigt att hitta en rymlig och kortfattad term som passade perfekt in i Twitter-hashtaggen. En av dessa termer föreslogs av Eric Evans från RackSpace - "NoSQL". Terminen var planerad för endast ett möte och hade ingen djup semantisk belastning, men det hände sig att den spred sig över hela det globala nätverket som en viral reklam och blev de facto namnet på en hel riktning inom IT-branschen. Förresten, Voldemort (Amazon Dynamo-klon), Cassandra, Hbase (analoger av Google BigTable), Hypertable, CouchDB, MongoDB talade på konferensen.

Det är värt att än en gång betona att begreppet "NoSQL" är helt spontant till sitt ursprung och inte har någon allmänt accepterad definition eller vetenskaplig institution bakom sig. Detta namn karakteriserar snarare vektorn för IT-utveckling bort från relationsdatabaser. Det står för Not Only SQL, även om det finns anhängare av den direkta definitionen av No SQL. Pramod Sadalaj och Martin Fowler försökte gruppera och systematisera kunskap om NoSQL-världen i sin färska bok "NoSQL Distillered".

2.2 Grundläggande egenskaper hos NoSQL-databaser

Det finns få gemensamma egenskaper för alla NoSQL, eftersom många heterogena system nu är gömda under NoSQL-etiketten (den kanske mest kompletta listan finns på http://nosql-database.org/). Många egenskaper är speciella endast för vissa NoSQL-databaser, jag kommer definitivt att nämna detta när jag listar dem.

1. Ingen SQL används

Jag menar ANSI SQL DML, eftersom många databaser försöker använda frågespråk som liknar den välkända favoritsyntaxen, men ingen har lyckats implementera det fullt ut och är osannolikt att lyckas. Även om det ryktas om startups som försöker implementera SQL, till exempel i hadup ( http://www.drawntoscalehq.com/ och http://www.hadapt.com/ ).

2. Ostrukturerad (schemalös)

Meningen är att i NoSQL-databaser, till skillnad från relationsdatabaser, är datastrukturen inte reglerad (eller svagt skriven, om vi drar analogier med programmeringsspråk) - du kan lägga till ett godtyckligt fält i en separat rad eller dokument utan att först deklarativt ändra strukturen av hela bordet. Således, om det finns ett behov av att ändra datamodellen, är den enda tillräckliga åtgärden att återspegla ändringen i applikationskoden.

Till exempel, när du byter namn på ett fält i 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"

Om vi ​​ändrar applikationslogiken förväntar vi oss ett nytt fält även vid läsning. Men på grund av avsaknaden av ett dataschema saknas totalSum-fältet från andra redan existerande Order-objekt. I den här situationen finns det två alternativ för ytterligare åtgärder.

Det första är att genomsöka alla dokument och uppdatera detta fält i alla befintliga dokument. På grund av datavolymen sker denna process utan några låsningar (jämförbart med kommandot alter table rename column), så under uppdateringen kan redan befintliga data läsas av andra processer. Därför är det andra alternativet - att checka in applikationskoden - oundvikligt:

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

Och redan när vi spelar in igen kommer vi att skriva detta fält till databasen i ett nytt format.

En trevlig konsekvens av frånvaron av ett schema är effektiviteten i att arbeta med sparsam data. Om ett dokument har ett date_published-fält och det andra inte har det skapas inget tomt datum_published-fält för det andra. Detta är i princip logiskt, men ett mindre uppenbart exempel är NoSQL-databaser i kolumnfamiljen, som använder de välbekanta begreppen tabeller/kolumner. Men på grund av avsaknaden av ett schema deklareras kolumner inte deklarativt och kan ändras/läggas till under en användares databassession. Detta tillåter i synnerhet användningen av dynamiska kolumner för implementering av listor.

Det ostrukturerade schemat har sina nackdelar - förutom den ovan nämnda overheaden i applikationskoden vid ändring av datamodellen - frånvaron av alla typer av restriktioner från basen (inte null, unik, kontrollbegränsning, etc.), plus det är ytterligare svårigheter att förstå och kontrollera strukturdata när man arbetar med databasen för olika projekt parallellt (det finns inga ordböcker på sidan av databasen). Men i en snabbt föränderlig modern värld är sådan flexibilitet fortfarande en fördel. Ett exempel är Twitter, som för fem år sedan, tillsammans med tweeten, bara lagrade lite extra information (tid, Twitter-handtag och ytterligare några bytes meta-information), men nu, förutom själva meddelandet, några fler kilobyte metadata lagras i databasen.

(Hedanefter talar vi huvudsakligen om nyckel-värde, dokument- och kolumnfamiljedatabaser, grafdatabaser kanske inte har dessa egenskaper)

2.3. Representation av data i form av aggregat (aggregat)

Till skillnad från relationsmodellen, som lagrar applikationens logiska affärsenhet i olika fysiska tabeller för normaliseringsändamål, fungerar NoSQL-butiker på dessa enheter som holistiska objekt:

Det här exemplet visar aggregationer för en standardkonceptuell relationsmodell för e-handel "Order - Orderartiklar - Betalningar - Produkt". I båda fallen kombineras beställningen med positioner till ett logiskt objekt, medan varje position lagrar en länk till produkten och några av dess attribut, till exempel namnet (en sådan denormalisering är nödvändig för att inte begära ett produktobjekt vid hämtning en order - huvudregeln för distribuerade system är "joins" mellan objekt). I ett aggregat kombineras betalningar med beställningen och är en integrerad del av objektet, i det andra placeras de i ett separat objekt. Detta visar huvudregeln för att designa en datastruktur i NoSQL-databaser - den måste följa applikationens krav och optimeras så mycket som möjligt för de vanligaste förfrågningarna.

Många kommer att invända och notera att arbetet med stora, ofta denormaliserade objekt är fyllt med många problem när man försöker godtyckliga frågor om data när frågor inte passar in i strukturen av aggregat. Vad händer om vi använder beställningar tillsammans med orderrader och betalningar (så här fungerar appen), men företaget ber oss att räkna hur många enheter av en viss produkt som såldes förra månaden? I det här fallet, istället för att skanna OrderItem-tabellen (i fallet med en relationsmodell), måste vi hämta hela beställningarna i NoSQL-lagring, även om vi inte behöver mycket av denna information. Tyvärr är detta en kompromiss som måste göras i ett distribuerat system: vi kan inte normalisera data som i ett konventionellt enserversystem,

Jag försökte gruppera för- och nackdelar med båda metoderna i en tabell: