2.1 Opkomst van de term NoSQL
Onlangs is de term "NoSQL" erg in de mode en populair geworden, onder dit teken worden allerlei softwareoplossingen actief ontwikkeld en gepromoot. NoSQL is synoniem geworden met enorme hoeveelheden data, lineaire schaalbaarheid, clusters, fouttolerantie, non-relationaliteit. Weinig mensen hebben echter een goed begrip van wat NoSQL-opslag is, hoe de term is ontstaan en welke gemeenschappelijke kenmerken ze hebben. Laten we proberen deze leemte op te vullen.
Het meest interessante aan de term is dat hij, ondanks dat hij eind jaren 90 voor het eerst werd gebruikt, pas echt betekenis kreeg in de vorm waarin hij nu wordt gebruikt medio 2009. Aanvankelijk was dit de naam van een open -brondatabase gemaakt door Carlo Strozzi, die alle gegevens opsloeg als ASCII-bestanden en shell-scripts gebruikte in plaats van SQL om toegang te krijgen tot de gegevens. Het had niets te maken met "NoSQL" in zijn huidige vorm.
In juni 2009 organiseerde Johan Oskarsson een bijeenkomst in San Francisco om nieuwe trends in de IT-opslag- en verwerkingsmarkt te bespreken. De belangrijkste aanleiding voor de bijeenkomst waren nieuwe open source-producten zoals BigTable en Dynamo. Voor een helder teken voor een vergadering was het nodig om een ruime en beknopte term te vinden die perfect in de Twitter-hashtag zou passen. Een van deze termen is voorgesteld door Eric Evans van RackSpace - "NoSQL". De term was gepland voor slechts één vergadering en had geen diepe semantische lading, maar het gebeurde zo dat het zich als een virale advertentie over het wereldwijde netwerk verspreidde en de de facto naam werd van een hele richting in de IT-industrie. Trouwens, Voldemort (Amazon Dynamo-kloon), Cassandra, Hbase (analogen van Google BigTable), Hypertable, CouchDB, MongoDB spraken op de conferentie.
Het is de moeite waard om nogmaals te benadrukken dat de term "NoSQL" volledig spontaan van oorsprong is en er geen algemeen aanvaarde definitie of wetenschappelijke instelling achter zit. Deze naam kenmerkt eerder de vector van IT-ontwikkeling weg van relationele databases. Het staat voor Not Only SQL, hoewel er voorstanders zijn van de directe definitie van No SQL. Pramod Sadalaj en Martin Fowler probeerden kennis over de NoSQL-wereld te groeperen en te systematiseren in hun recente boek "NoSQL Distilled".
2.2 Basiskenmerken van NoSQL-databases
Er zijn weinig gemeenschappelijke kenmerken voor alle NoSQL, aangezien veel heterogene systemen nu verborgen zijn onder het NoSQL-label (misschien is de meest volledige lijst te vinden op http://nosql-database.org/). Veel kenmerken zijn alleen eigen aan bepaalde NoSQL-databases, ik zal dit zeker vermelden bij het aanbieden.
1. Er wordt geen SQL gebruikt
Ik bedoel ANSI SQL DML, aangezien veel databases querytalen proberen te gebruiken die vergelijkbaar zijn met de bekende favoriete syntaxis, maar niemand is erin geslaagd deze volledig te implementeren en het is onwaarschijnlijk dat dit zal lukken. Al gaan er geruchten dat startups SQL proberen te implementeren, bijvoorbeeld in hadup ( http://www.drawntoscalehq.com/ en http://www.hadapt.com/ ).
2. Ongestructureerd (schemaloos)
De betekenis is dat in NoSQL-databases, in tegenstelling tot relationele databases, de datastructuur niet gereguleerd is (of zwak getypeerd, als we analogieën trekken met programmeertalen) - je kunt een willekeurig veld toevoegen aan een aparte regel of document zonder eerst de structuur declaratief te veranderen van de hele tafel. Dus als het nodig is om het gegevensmodel te wijzigen, is de enige voldoende actie om de wijziging in de applicatiecode weer te geven.
Bijvoorbeeld bij het hernoemen van een veld 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"
Als we de applicatielogica veranderen, verwachten we ook bij het lezen een nieuw veld. Maar vanwege het ontbreken van een gegevensschema ontbreekt het veld totalSum in andere reeds bestaande Order-objecten. In deze situatie zijn er twee opties voor verdere actie.
De eerste is om alle documenten te crawlen en dit veld bij te werken in alle bestaande documenten. Vanwege de hoeveelheid gegevens vindt dit proces zonder enige vergrendeling plaats (vergelijkbaar met de opdracht kolom wijzigen tabel hernoemen), dus tijdens de update kunnen reeds bestaande gegevens door andere processen worden gelezen. Daarom is de tweede optie - het inchecken van de applicatiecode - onvermijdelijk:
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
En als we opnieuw opnemen, schrijven we dit veld in een nieuw formaat naar de database.
Een prettig gevolg van het ontbreken van een schema is de efficiëntie van het werken met schaarse gegevens. Als het ene document een datum_gepubliceerd veld heeft en het tweede niet, dan wordt er geen leeg datum_gepubliceerd veld gemaakt voor het tweede document. Dit is in principe logisch, maar een minder voor de hand liggend voorbeeld zijn NoSQL-databases uit de kolomfamilie, die de bekende concepten van tabellen / kolommen gebruiken. Vanwege het ontbreken van een schema worden kolommen echter niet declaratief gedeclareerd en kunnen ze worden gewijzigd/toegevoegd tijdens de databasesessie van een gebruiker. Dit maakt met name het gebruik van dynamische kolommen voor de implementatie van lijsten mogelijk.
Het ongestructureerde schema heeft zijn nadelen - naast de bovengenoemde overhead in de applicatiecode bij het wijzigen van het datamodel - het ontbreken van allerlei restricties vanuit de basis (niet null, uniek, check constraint etc.), plus daar zijn extra problemen bij het begrijpen en beheersen van de structuurgegevens bij het parallel werken met de database van verschillende projecten (er zijn geen woordenboeken aan de zijkant van de database). In een snel veranderende moderne wereld is dergelijke flexibiliteit echter nog steeds een voordeel. Een voorbeeld is Twitter, dat vijf jaar geleden naast de tweet nog maar weinig extra informatie opsloeg (tijd, Twitter-handle en nog een paar bytes aan meta-informatie), maar nu naast het bericht zelf nog wat meer kilobytes aan metadata worden opgeslagen in de database.
(Hierna hebben we het voornamelijk over sleutel-waarde-, document- en kolomfamiliedatabases, grafische databases hebben deze eigenschappen mogelijk niet)
2.3. Weergave van gegevens in de vorm van aggregaten (aggregaten)
In tegenstelling tot het relationele model, dat de logische bedrijfsentiteit van de toepassing opslaat in verschillende fysieke tabellen voor normalisatiedoeleinden, werken NoSQL-winkels op deze entiteiten als holistische objecten:
Dit voorbeeld toont aggregaties voor een standaard conceptueel relationeel model voor e-commerce "Bestelling - Bestelitems - Betalingen - Product". In beide gevallen wordt de volgorde gecombineerd met posities tot één logisch object, terwijl elke positie een link naar het product en enkele van zijn attributen opslaat, bijvoorbeeld de naam (een dergelijke denormalisatie is nodig om geen productobject op te vragen bij het ophalen een volgorde - de hoofdregel van gedistribueerde systemen is "joins" tussen objecten). In het ene aggregaat worden betalingen gecombineerd met de bestelling en zijn ze een integraal onderdeel van het object, in het andere worden ze in een apart object geplaatst. Dit demonstreert de hoofdregel voor het ontwerpen van een datastructuur in NoSQL-databases: deze moet voldoen aan de vereisten van de applicatie en zoveel mogelijk worden geoptimaliseerd voor de meest voorkomende verzoeken.
Velen zullen bezwaar maken, en merken op dat het werken met grote, vaak gedenormaliseerde objecten veel problemen met zich meebrengt bij het uitvoeren van willekeurige query's op gegevens wanneer query's niet passen in de structuur van aggregaten. Wat als we bestellingen samen met orderregelitems en betalingen gebruiken (zo werkt de app), maar het bedrijf ons vraagt om te tellen hoeveel eenheden van een bepaald product er vorige maand zijn verkocht? In dit geval zullen we, in plaats van de OrderItem-tabel te scannen (in het geval van een relationeel model), de volledige bestellingen in NoSQL-opslag moeten ophalen, hoewel we niet veel van deze informatie nodig zullen hebben. Helaas is dit een compromis dat moet worden gesloten in een gedistribueerd systeem: we kunnen gegevens niet normaliseren zoals in een conventioneel systeem met één server,
Ik heb geprobeerd de voor- en nadelen van beide benaderingen in een tabel te groeperen:
GO TO FULL VERSION