- Apache HBase (Beschrieben in [Fondermann, Spichale und George 2014, Kapitel 3], [Wolff et al. 2013, Kapitel 4], [Edlich, Friedland, Hampe u.a. 2011, S. 64ff].
- Amazon SimpleDB. Beschrieben in [Edlich, Friedland, Hampe u.a. 2011, S. 96ff]
- CouchDB. Beschrieben in [Kurowski 2012, Kapitel 2], [Wolff, Nitschinger und Trelle 2014, Kapitel 2], [Edlich, Friedland, Hampe u.a. 2011, S. 118ff], [Gull 2011]
- MongoDB. Beschrieben in [Kurowski 2012, Kapitel 3], [Wolff, Nitschinger und Trelle 2014, Kapitel 4], [Edlich, Friedland, Hampe u.a. 2011, S. 131ff].
- Redis. Beschrieben in [Kurowski 2012, Kapitel 4], [Edlich, Friedland, Hampe u.a. 2011, S. 152ff], [Trelle 2014].
- Cassandra. Beschrieben in [Wolff et al. 2013, Kapitel 3], [Edlich, Friedland, Hampe u.a. 2011, S. 82ff]
- Riak (NoSQL-Key-Value-Store). Beschrieben in [Wolff, Nitschinger und Trelle 2014, Kapitel 3], [Edlich, Friedland, Hampe u.a. 2011, S. 179ff].
- Neo4j. [Wolff et al. 2013, Kapitel 2], [Edlich, Friedland, Hampe u.a. 2011, S. 290ff]
- ArangoDb von triAGENS (hps@ct.de). Quelloffen mit Applikations-Framework Foxx 2.0.
Vgl. die Übersicht zu NoSQL-Datenbanken in [Edlich, Friedland, Hampe u.a. 2011, S. 371ff] ("Orientierung im Datenbankraum"). |
|
Im Folgenden werden nun weitere Begriffe und Konzepte aus diesem Umfeld geklärt und die angeführten Typen datenverwaltender Anwendungssysteme genauer betrachtet. |
|
20.2.4 Volume, Velocity, Variety |
|
Mit diesem Datenumfang sind meist auch Aufgaben verbunden, die mit Relationalen Datenbanksystemen kaum zu lösen sind. Diese grundlegenden Herausforderungen im BigData-Umfeld werden in der Literatur oft durch die Stichworte Volume, Velocity und Variety (3V) beschrieben: |
|
- Volume: Masse an Daten, die pro Zeiteinheit gespeichert werden müssen. Diese ist in BigData-Anwendungsbereichen sehr groß.
- Velocity: Geschwindigkeit, mit der die Daten persistent gespeichert und verarbeitet werden (Batch oder in Echtzeit). Diese muss, v.a. wegen der Datenmenge, sehr hoch und auch mittels der Systemarchitektur gesichert sein.
- Variety: Unterschiedlichkeit der Daten, oft beschrieben als unterschiedliche Grade von Strukturiertheit mit der Skala völlig unstrukturiert, semistrukturiert, stark strukturiert.
|
|
Solche Anwendungen sind (beim heutigen Stand der Technik) im Regelfall nur mit verteilten Systemen realisierbar. Diese müssen darüberhinaus leicht skalierbar sein, Parallelverarbeitung erlauben, Replikation von Daten erleichtern und eine hohe Ausfallsicherheit aufweisen. |
Anforderungen |
20.2.5 Skalierbarkeit |
|
In diesen Anwendungsbereichen liegen nicht nur große Datenmengen vor, die meist auf verteilten Systemen betrieben werden müssen, sondern solche, deren Umfang sich auch kurzfristig verändern kann. Daran müssen die datenverwaltenden Systeme angepasst werden. Diese Fähigkeit wird Skalierbarkeitgenannt und nach horizontal und vertikal unterschieden. |
|
Vertikale Skalierbarkeit meint den Ausbau der eigenen Hardware. Also z.B. durch Nutzung größerer Server. Um es mit [Kurowski 2012, Kapitel 1] zu sagen: |
Vertikale Skalierbarkeit |
"Vertikale Skalierung ist das Tuning einer abgeschlossenen Datenbankeinheit durch Hinzufügen von Rechenleistung oder Speicher, ....." |
|
Und evtl. durch Umstellung auf eine InMemory-Lösung (vgl. Abschnitt 17.8), kann man ergänzen. Dies alles reicht derzeit (wer kann die Entwicklung der Hardware schon prognostizieren?) allerdings nicht aus für die in den BigData - Anwendungsbereichen anfallenden Daten, weshalb hier die horizontale Skalierbarkeit benötigt wird. |
|
Horizontale Skalierbarkeit meint den Ausbau des Netzwerks, in dem die Daten verwaltet werden. Dies erfolgt durch das Hinzufügen weiterer abgeschlossener Datenbankeinheiten. Sie ist für die Bewältigung großer Datenmengen oft die bessere Alternative bzw., ab einer gewissen Datenmenge die einzige Möglichkeit (es muss immer wieder gesagt werden: beim derzeitigen Stand der Hardwaretechnologie). Das bedeutet, dass für größere Datenmengen oder höhere Performanceanforderungen einfach mehr Server genutzt werden und umgekehrt Server wegfallen, wenn die Anforderungen geringer werden. |
Horizontale Skalierbarkeit |
Nun bedarf die Skalierbarkeit nicht nur einer angemessenen Hardwarelösung, sprich Netzwerkstruktur, sondern auch eines datenverwaltenden Systems, mit dem die Skalierung realisiert werden kann (grundsätzlich, bzw. in vertretbarem zeitlichen Aufwand). Relationale Datenbanken leisten dies nur eingeschränkt. Edlich et al. fassen ihre diesbezüglichen Erkenntnisse wie folgt zusammen: Der Einsatz relationaler Datenbanksysteme führt zu ... |
Geeignete datenverwaltende Systeme |
"... nicht vertretbaren Antwortzeiten, insbesondere bei gleichzeitiger Replikation, die oft auch gewünscht ist. ... Sobald Tabellen und Indizes eine Datenmenge erreicht hatten, die eine Verteilung über mehr als eine Maschine erfordert, stellten die verantwortlichen Entwickler und Administratoren fest, dass sie für eine akzeptable Reaktionszeit nur mit Workarounds und Eingriffen in den Quellcode der verwendeten Datenbanksysteme Herr der Lage werden konnten" [Edlich, Friedland, Hampe u.a. 2011, S. 30]. |
|
Dies ist ohne Probleme nachvollziehbar. Für relationale Datenbanken gilt wegen der ausgeprägten internen Verknüpfungsstruktur (vgl. Kapitel 5 bis 13 in [Staud 2015]), die wiederum durch die Art der Daten begründet ist, die Notwendigkeit, Transaktionen nach den ACID-Prinzipien zu realisieren. Dies ist ein Kernprinzip der Architektur relationaler Datenbanksysteme. Nur so kann die Konsistenz dieser intensiv verknüpften Daten aufrechterhalten werden. |
|
Es werden also andere datenverwaltende Systeme und im Übrigen auch "einfachere" Datenstrukturen benötigt. Da fügt es sich gut, dass ein "Großteil der Daten im Web 2.0 ohne Relationen" (gemeint sind die Beziehungen zwischen Tabellen bzw. Basiskomponenten) sind, so [Edlich, Friedland, Hampe u.a. 2011, S. 151]. |
|
Insgesamt also: Für relationale Datenbanken reicht es aus bzw. muss es (will man gute Reaktionszeiten) ausreichen, vertikal zu skalieren, indem eine leistungsfähigere Hardware angeschafft wird, bis hin zu InMemory-Lösungen (vgl. Abschnitt 17.8 für eine sehr kurze und Abschnitt 24.11 in [Staud 2015] für eine etwas ausführlichere Beschreibung). Mit dem Internet-Boom entstanden Datenmengen, die (in der derzeitigen Entwicklungsphase) nur durch verteilte Verarbeitung bewältigt werden können und die einer horizontalen Skalierbarkeit bedürfen. |
|
20.2.6 Parallelisierung mit Hilfe des MapReduce-Frameworks |
|
Zur horizontalen Skalierung und zur Lösung rechenintensiver Aufgaben gehört die Parallelverarbeitung. Nur wenn die jeweilige Aufgabe sich auf die Rechner im Netz verteilen lässt, kann sie in angemessener Zeit gelöst werden. Voraussetzung für BigData-Lösungen ist also ein Programmiermodell, das sich leicht parallellisieren lässt [Wartala 2014, S. 17]. Z.B. das MapReduce-Framework. Dies ist ein Programmiermodell für die Kopplung verteilter Dateisysteme, auch Cluster-Dateisystem genannt [Wartala 2012, S. 18]. Kerngedanke ist die Daten-Lokalität. |
Aufgaben verteilen |
"Die Verarbeitung großer Datenmengen auf einem verteilten System ist nur sinnvoll, wenn diese Daten den jeweiligen Verarbeitungsprozessen zur Verfügung stehen, sprich: Die Anwendungen müssen zu den Daten kommen, nicht die Daten zu den Anwendungen" [Wartala 2012, S. 17]. |
|
Es geht also, mit anderen Worten, um die nebenläufige Berechnung in Computerclustern, bei der Seiteneffekte wie Verklemmungen (deadlock) und Wettlaufsituationen (race conditions) vermieden werden. |
|
Realisierung |
|
Im Kern ist dies wie folgt realisiert. Eine Funktion map() (Map-Funktion) nimmt als Eingabeparameter eine Liste mit Key/Value-Paaren und eine Funktion für deren Verarbeitung entgegen und verarbeitet sukzessive alle Elemente der Liste. Sie gibt dann die durch die Funktion modifizierte Liste (wiederum Key/Value-Paare) zurück. Im Rahmen einer konkreten Verarbeitung entstehen mehrere solcher Listen. Diese werden mit Hilfe einer Funktion reduce() (Reducer-Funktion) zusammengeführt und weiterverarbeitet. Bezogen auf ein verteiltes Dateisystem auf vielen Rechnerknoten eines Clusters, stellt sich dies wie folgt dar: Auf jedem Rechnerknoten werden die Daten zur Verfügung gestellt, die genau der Map-Prozess auf diesem Rechner benötigt. Dann werden parallel die Ergebnislisten der Mapper-Funktionen eingesammelt und nach erfolgreicher Weiterverarbeitung (Reduzierung) wieder in das verteilte Dateisystem geschrieben. |
Key/Value-Paare |
Es geht also nur um die Verarbeitung von Key/Value-Paaren mit ihrer doch recht mageren Semantik. Dies ist gegenüber den Möglichkeiten von SQL deutlich vereinfacht. Die Semantik muss dann vom Anwendungsprogramm geliefert werden. Entwickelt wurde dieses Programmiermodell von Google-Entwicklern. |
|
Weiter gehende Beschreibungen finden sich in [Wartala 2012, S. 17], [Edlich, Friedland, Hampe u.a. 2011, S. 17], [Fondermann, Spichale und George 2014, Kapitel 2] und [Schrempp 2012, Kapitel 2]. |
|
Hadoop ist ein auf Java basierendes Open Source Framework für die skalierbare und verteilte Verarbeitung großer Datenmengen auf vielen Rechnern innerhalb eines Netzwerks. Es implementiert den MapReduce-Algorithmus auf einem verteilten Dateisystem [Wartala 2012, S. 9]. Vorgeschlagen wurde es erstmals von Google [Wartala 2012, S. 21] für deren Dateisystem HDFS. Dies ist ein sog. verteiltes Dateisystem, kann also über Rechnergrenzen hinaus existieren. Vgl. für eine Beschreibung [Wartala 2012, S. 22ff]. |
Hadoop |
Hadoop wird z.B. für HBase benötigt (Vgl. [Fondermann, Spichale und George 2014, Kapitel 1], [Wartala 2012]). |
|
20.2.7 Konsistenz, CAP-Theorem |
|
In der für BigData-Anwendungsbereiche notwendigen (Datenbank- und System-) Architektur können nicht die üblichen datenbanktechnischen Forderungen an Konsistenz und Transaktionssicherheit erfüllt werden (vgl. zu ACID-Transaktionen [Staud 2015, Abschnitt 19.9]). Von den gewünschten Eigenschaften (absolute) Konsistenz, (hohe) Verfügbarkeit und Ausfalltoleranz können, so zeigte es zuerst Eric Brower im so genannten CAP-Theorem, nur zwei realisiert werden. |
|
Zuerst die drei Ziele: |
|
(1) Konsistenz (C von Consistency) bezogen auf Transaktionen. |
|
Dies bedeutet, dass die verteilte Datenbank nach Abschluss einer Transaktion einen konsistenten Zustand erreicht. Dabei geht es v.a. darum, dass bei einer Änderung der Daten in einem Knoten, alle folgenden Lesezugriffe - egal über welchen Knoten - den aktualisierten Wert liefern. Dies bedeutet, dass der aktualisierte Wert erst dann wieder gelesen werden kann, wenn alle replizierenden Knoten aktualisiert sind. Beispiel: Wenn in einem WebShop eine Bestellung getätigt und der Lagerbestand verändert wird, sollte die nächste Abfrage des Lagerbestandes erst erfolgen können, wenn alle Knoten den aktualisierten Wert aufweisen. |
|
(2) Verfügbarkeit (A von Availability) eines Datenservice bezogen auf ein Netz. |
|
Systeme müssen weiterarbeiten, auch wenn eines der Systeme nicht mehr antwortet. Dies beruht auf der Forderung nach einer akzeptablen Reaktionszeit. Bei Bestellvorgängen im E-Commerce sind schnelle Reaktionen nötig, sonst sinkt der Umsatz. |
|
(3) Ausfalltoleranz (P von Partition Tolerance). |
|
Der Ausfall eines Knotens oder einer Kommunikationsverbindung zwischen den Knoten einer verteilten Datenbank soll nicht zum Ausfall des gesamten Systems führen, sondern das System soll weiterhin auf Anfragen von außen reagieren können. |
|
Nur zwei dieser Ziele können erreicht werden. Da die hohe Verfügbarkeit und die Ausfalltoleranz als absolut dominant angesehen werden, muss man die Anforderungen an die Konsistenz lockern. Somit muss das eigentliche Konsistenzmodell ACID durch ein anderes ersetzt werden, das BASE (Lauge) genannt wird. Mit ihm sind die Hauptanforderungen an horizontal skalierte Datenbanksysteme wie folgt formuliert: |
Alternatives Konsistenzmodell BASE |
- BA von Basically Available: Das System ist erstmal grundsätzlich immer verfügbar.
- S von Soft State: Der Zustand des Systems ist nicht immer gleich.
- E von Eventually Consistent: Der Datenbestand ist nicht immer gleich wieder konsistent [Kurowski 2012]
|
|
Bezüglich der Konsistenz wird nur verlangt, dass "irgendwann" der konsistente Zustand wieder erreicht wird und nicht nach jeder Transaktion. Dieses Ziel kann auf unterschiedliche Art erreicht werden. Vgl. hierzu und zu den Wegen, wie dieses Ziel erreicht werden kann [Edlich, Friedland, Hampe u.a. 2011, S. 34]. |
|
20.2.8 Schemafreiheit |
|
Schema meint hier die logische Struktur der Daten, wie sie aus einem Datenmodell abgeleitet wurde. Nun geht es natürlich nicht ohne ein Schema. Schon die Festlegung einer Key/Value-Struktur (die unabdingbar ist, will man Informationen erfassen) ist ein Schema. Werden dann zur Modellierung von Objekten Tupel gebildet, ist der Schema-Aspekt noch deutlicher. |
Ohne Schema? |
Die folgenden Ausführungen beziehen sich auf Dokumentendatenbanken (vgl. Abschnitt 20.2.11), weil hier dieses Thema die größte Bedeutung besitzt. Für die Zwecke dieses Kapitels genügt es, sich zu Beginn ein Dokument wie einen Datensatz vorzustellen (vgl. die Beispiele unten). |
|
Drei Faktoren waren die Treiber für diese Entwicklung hin zur Schemafreiheit: |
|
(1) Die Tatsache, dass Dokumente über irgendwelche Objekte sehr unterschiedlich sein können. Nehmen wir z.B. Personen. Der eine ist Programmierer, der andere arbeitet in der Hausverwaltung, beide gemeinsame Attribute, aber auch spezifische. Abgebildet auf die relationale Theorie liegt damit folgende Struktur vor: Alle Objekte haben bestimmte Attribute gemeinsam, andere sind nur für bestimmte Objekte gültig. In der relationalen Theorie wird dies durch Normalisierung, Zerlegung der Relationen und Einfügen von relationalen Verknüpfungen bewältigt. Dies ist aber in NoSQL-Anwendungen nicht gern gesehen (bzw. nicht möglich). |
|
(2) Einzelne Dokumente sind verschachtelt. D.h. ein Key/Value-Paar kann auch wieder ein Objekt sein, eine Liste enthalten, usw. |
|
(3) Änderungen des Schemas kommen, wegen der Dynamik dieser Anwendungsbereiche, oft vor. Diese sollten mit wenig Aufwand und schnell realisiert werden können. Z.B. wenn neue Attribute hinzukommen oder vorhandene wegfallen. |
|
Eines der Mittel, die Schemafreiheit zu realisieren, ist Versionierung, d.h. Versionen von Werten (z.B. Attributsausprägungen) zu halten. Zum Beispiel kann die Anwendung von Anfang an erweiterte Daten nutzen (mit einem Feld mehr als aktuell benötigt), ein Hintergrundprozess konvertiert die Daten und schreibt sie als neue Version. Es gibt dann nur ein kleines Zeitfenster, in dem das Lesen der Daten die alte Version ohne das neue Feld zurückliefert, was in diesen Anwendungsbereichen als tolerierbar angesehen wird. |
Versionierung |
Insgesamt ist mit dem Begriff Schemafreiheit auch gemeint, dass das vorhandene Schema zur Laufzeit ohne großen Aufwand geändert werden kann und dass die einzelnen Dokumente einen unterschiedlichen Aufbau (eine unterschiedliche Attributzusammensetzung) haben können. Wolff et al. beschreiben dies am Beispiel von Cassandra wie folgt: |
Schemafreiheit |
Zur Laufzeit können weitere Spalten (gemeint sind Attribute, ...) hinzugefügt werden, "ohne dass das Cassandra-Schema explizit geändert werden muss. So könnte beispielsweise eine Entität Benutzer um zusätzliche Attribute zur Erfassung des Geburtsdatums und des Geburtsorts erweitert werden, ohne dass Attribute zuvor definiert werden" [Wolff et al. 2013, Kapitel 3]. |
|
Wolff et al. weisen aber auch darauf hin (wiederum am Beispiel Cassandra), dass es den Prozess des Schemadesigns doch gibt: |
Cassandra |
"Der Keyspace sowie die notwendigen Spaltenfamilien mit all ihren Parametern sollten vorab definiert werden. Columns mit einem Sekundärindex müssen zwingend definiert werden." |
Columns=
Spalten=
Attribute |
Sie weisen dann darauf hin, dass hier, wie bei Relationalen Datenbanksystemen, das Schema auch noch nachträglich geändert werden kann und dass deshalb die Bezeichnung "dynamisches Schema" geeigneter wäre [Wolff et al. 2013, Kapitel 3]. |
|
Hier einige Beispiele für konkrete Umsetzungen und deren Konsequenzen. Wolff et al. beschreiben den Modellierungsaspekt mit "BigTable und damit HBase" wie folgt: Das logische Datenmodell ähnelt dem relationalen (mit Tabellen, Zeilen und Spalten). Es gibt aber keine referentielle Integrität, keine Transaktionen und beliebige Indexe und kein SQL. Der Zugriff erfolgt mit einer einfachen API mit nur vier Befehlen (Put, Get, Scan und Delete). Zeilen (Tupel) haben einen eindeutigen Schlüssel (row key) mit dem die Anwender auf die eigentlichen Spalten zugreifen können, die ebenfalls einen Schlüssel haben (column key). Als Folge der notwendigen oben beschriebenen eingeschränkten Konsistenz muss versioniert werden. Dies geschieht auf unterschiedliche Weise. Bei HBase werden die Werte in den Zeilen versioniert und - so die systemweite Vorgabe - drei Versionen der Werte aufgehoben. Auch ein Zeitstempel ist für die Daten möglich, dann kann man auch auf historische Werte zugreifen [Wolff et al. 2013, Kapitel 4]. |
BigTable, HBase |
Trelle beschreibt die Situation für MongoDB. An sich, führt er aus, gilt MongoDB als schemafrei, trotzdem nimmt das Schemadesign einen hohen Stellenwert ein. Er sieht die Schemafreiheit als einen "rein technischen Aspekt", der für performante Anwendungen und zur Beherrschung der fehlenden dokumentenübergreifenden Transaktionen durch Überlegungen zur Strukturierung der Datenablage ergänzt werden muss. [Trelle 2014, S. 177f] |
MongoDB |
Auch Wolff et al. weisen auf die Schemaflexibilität von MongoDB hin: |
|
"Es gibt keinen Mechanismus, der Dokumenten innerhalb einer Collection eine bestimmte Struktur oder Datentypen für bestimmte Felder aufzwingt ..... Ob es fachlich Sinn macht, völlig unterschiedliche Dokumentarten in einer Collection zu verwalten, beurteilen Sie besser selbst." [Wolff, Nitschinger und Trelle 2014] |
|
Abschließend hierzu noch ein Beispiel aus [Trelle 2014, S. 17], ein Produktkatalog mit unterschiedlichen Produkttypen innerhalb einer Collection: |
|
> db.produkte.insert({
|
|
typ: "dvd",
|
|
titel: "Lost Higway",
|
|
regie: "DavidLynch"
|
|
})
|
|
> db.produkte.insert({
|
|
typ: "cd",
|
|
titel: "Highway to hell",
|
|
band: "AC/DC"
|
|
})
|
|
Die zwei Befehle fügen jeweils ein Dokument (einen Datensatz) ein, allerdings mit jeweils einem unterschiedlichen Attribut. |
|
In der Sprache der relationalen Theorie kann die flexible Schemabildung in diesem Bereich der NoSQL-Welt (Dokumente) wie folgt zusammengefasst werden: |
|
- Die Schemabildung besteht darin, Objekte zu identifizieren und ihnen Eigenschaften (Attribute, Key/Values, ...) zuzuordnen.
- Die Objekte werden in Collections gruppiert.
- Key/Value-Paare können verschachtelt sein und Informationen aller Art enthalten.
- Dokumente bestimmter Objekte können unterschiedliche Key/Value-Paare aufweisen.
- Neue Attribute können bei einem "neuen Dokument" einfach hinzugefügt und überflüssig gewordene einfach gelöscht werden.
- Theoretisch könnten auch Dokumente abgespeichert werden, deren Schnittmenge gemeinsamer Attribute nur sehr gering ist. Dass dies nicht sinnvoll ist, wird auch im obigen Zitat von Wolff et al. deutlich.
- Es gibt keine Verknüpfung zwischen unterschiedlichen Objekttypen, nur einfache Verweise sind bei einigen Systemen möglich.
- Es gibt keine Transaktionen über die Grenzen von Collections.
- Feldnamen müssen bei jedem Dokument mit abgespeichert werden [Trelle 2014, S. 33].
Dies sollte das Ausmaß an Flexibilität aufzeigen wie auch ihre Konsequenzen andeuten. Zu den Konsequenzen gehört der Verzicht auf die Ausmodellierung von Zusammenhängen zwischen den Daten. Schrempp beschreibt dies wie folgt: |
|
"Aufgrund des einfachen Datenmodells dieser Technologien wird bei NoSQL meistens ein Ansatz verwendet, bei dem die Daten so vorliegen, dass alle relevanten im Datensatz selber vorhanden sind und keine Navigation zu anderen Datensätzen nötig ist. Beispielsweise können mit einem Kunden auch gleich seine Bestellungen gespeichert werden" [Schrempp 2012, Pos. 216]. |
|
In den folgenden Kapiteln wird nun zuerst das Key/Value – Konzept vorgestellt und mit dem Atribut-Konzept verglichen, anschließend werden die wichtigsten Datenbank(system)typen aus diesem Bereich kurz vorgestellt. |
|
20.2.9 Key/Value vs. Attribut |
|
Vorbemerkung für Leser, die keinen Kontakt mit der Datenbanktheorie hatten: |
|
Oben war schon mehrfach von Anwendungsbereichen die Rede. Hier – im Datenbankkontext – wird der Begriff auch verwendet. Er beschreibt hier den Teil der Welt über den eine Datenbank errichtet werden soll. Also z.B. die Finanzbuchhaltung des Unternehmens, die Geschäftstätigkeit eines Internet-Unternehmens oder ein Unternehmen als Ganzes. Bei letzterem entstehen unternehmensweite Datenbanken, z.B. als Grundlage einer ERP-Software. |
|
In dem jeweiligen Anwendungsbereich werden dann (typischerweise) Objekte und Beziehungen (zusammengefasst: Informationsträger) zwischen diesen identifiziert und durch (für die Datenbank wichtige) Eigenschaften beschrieben. Zur Erfassung dieser Eigenschaften dienen Key/Values bzw. Attribute. Vgl. für eine vertiefte Beschreibung des Attributkonzepts [Staud 2015]. |
|
Ganz am Anfang des Datenbankdesigns und der Datenmodellierung muss geklärt werden, wie die Eigenschaften von Objekten und Beziehungen (Informationsträgern) erfasst werden, denn diese sind Grundlage jeglicher Datenbank. Bis vor einiger Zeit wurde dies über das Attributkonzept realisiert, weshalb so gut wie alle Datenbanken attributbasiert waren. D.h., alle Datenbanken (v.a. relationale) hatten Attribute zur Beschreibung der Informationsträger des jeweiligen Anwendungsbereichs. |
„SQL-Datenbanken“ |
Dies änderte sich mit den NoSQL-Datenbanken. Hier gewann ein Konzept Bedeutung, das mit Key/Value beschrieben wird. Wegen dessen großer Bedeutung und v.a. wegen der Konsequenzen dieser Abwendung vom Attributbegriff werden hier die beiden Konzepte vergleichend dargestellt. |
|
Das Attributkonzept |
|
Für eine vertiefte Betrachtung vgl. [Staud 2015], insbesondere Kapitel 2. |
|
Betrachten wir die folgende Abbildung. Ein Attribut erfasst das, was umgangssprachlich als Eigenschaft aufgefasst wird. Im Datenbankumfeld sind dies Eigenschaften von Objekten und Beziehungen. Vgl. Pos. [3] in der Abbildung. Dies können Namen, Semesterzahl oder ein BMI (Body Mass Index) sein. |
Pos. [3] |
Zu den Eigenschaften gehören die Objekte und Beziehungen, auf die sich die Attribute beziehen. Vgl. Pos. [2]. Dies können z.B. Angestellte (für die Eigenschaft Namen), Studierende (für die Eigenschaft Semesterzahl) oder „Sportlich aktive“ sein (für die Eigenschaft BMI). |
Pos. [2] |
Diese Objekte und Beziehungen gehören wiederum zu einem bestimmten Anwendungsbereich. Vgl. Pos. [1]. Im Beispiel der Abbildung Unternehmen (für die Angestellten), Hochschulen (für die Studierenden) und Fitnessclub (für die sportlich aktiven). |
Pos. [1] |
Darauf baut das Attributkonzept auf. Die Sachverhalte sind lediglich etwas formaler gefasst. In Position [4] ist dies angedeutet. |
Pos. [4] |
Zu jedem Attribut gehört der Anwendungsbereich, für den das Attribut eingerichtet wurde. Er stellt sozusagen das weitere Umfeld dar und kann evtl. in der Datenbankbezeichnung aufschimmern. Hier entsprechend dem Obigen Unternehmen, Hochschule, Fitnessclub. |
(a) |
Jedes Attribut bezieht sich auf bestimmte Informationsträger (Relationen in relationalen Datenbanken; Entitätstypen in der semantischen Modellierung; Objekte in objektorientierten Datenbanken). Hier zum Beispiel die Angestellen eines Unternehmens, die Studierenden einer Hochschule oder Menschen in einem Fitnessclub. |
(b) |
Jedes Attribut hat eine Bezeichnung, hier Name, Semesterzahl und BMI (Body Mass Index). Diese wird Attributsbezeichnung genannt. |
(c) |
Schlussendlich kann jedes Attribut bestimmte Werte annehmen. Diese werden als Attributsausprägungen bezeichnet. Hier wurden beispielhaft Widmer und Maier für das Attribut Name; 2, 7, 6 für die Semesteranzahl und 22.5 bzw. 29.2 als Wert des BMI angegeben. |
(d) |
Für die konkrete Nutzung in einer relationalen Datenbank wird jedes Attribut in der zugehörigen Relation angelegt und mit einem Datentyp sowie einer Eingrenzung der Attributsausprägungen und evtl. semantischen Integritätsbedingungen versehen. Eine vertieftere Darstellung hierzu, auch mit Berücksichtigung von Beziehugnen, findet sich in [Staud 2015], Kapitel 18 und 20. |
|

|
|
|
Abbildung 20.2-1: |
Das Attributkonzept |
|
|
|
Soweit – in aller Kürze – das Attributkonzept. Werfen wir nun einen Blick auf das Key/Value-Konzept. |
|
Key/Value-Konzept |
|
Das Key/Value – Konzept dient auch, wie das Attributkonzept, zur Erfassung von Eigenschaften zum Zwecke der Datenverwaltung. Dabei meint Value den Wert, den die Eigenschaft im konkreten Fall annnimmt und Key eine identifizierende Information für diesen Wert, also einen Schlüssel. |
|
Die folgende Abbildung zeigt einige Beispiele. Im Beispiel (1) geht‘s um die Nachnamen der Angestellten eines Unternehmens. Den Personalnummern als Key sind die Nachnamen als Values zugeordnet. |
Keine Meta-Informationen in den Daten |
Beispiel (2) gibt für die Studierenden einer Hochschule die Anzahl der bereits abgeleisteten Semester an. Als Key dient hier die Matrikelnummer, als Value die Semesterzahl. |
|
Beispiel (3) gibt die Bezeichnungen von Abteilungen an. Jeweils einer eindeutigen Abteilungsnummer (Key) ist die Abteilungsbezeichnung (Value) zugeordnet. |
|
Beispiel (4) gibt für jede Abteilungsbezeichnung die Zahl der Mitarbeiter an. Hier dient also die Abteilungsbezeichnung als Key. |
|
Dies sind auch schon alle Informationen, die im datenverwaltenden System vorliegen. Die in der Abbildung angegebenen Hinweise auf den jeweiligen Anwendungsbereich, die Informationsträger und die Bezeichnung der Eigenschaft sind in den Daten des datenverwaltenden Systems nicht vorhanden. Sie müssen entweder im Anwendungsprogramm oder in eigenen Datenbeständen verwaltet werden. |
|
Datenverwaltende Systeme dieses Typs verwalten also Daten, die lediglich aus einem Schlüssel und einem Wert bestehen, wobei der Begriff "Schlüssel" sich auf die jeweilige Eigenschaft bezieht, nicht auf die gesamte beschreibende Information eines Objekts (vgl. die Anmerkung zu diesem Key-Begriff unten). |
|
Der Wert einer solchen Key/Value-Kombination, diese wird hier auch Datensatz genannt wie die objektbeschreibenden Gegenstücke mit mehreren Attributen der physischen Datenorganisation, ist in der Regel ein Byte-Array. |
|
Kurowski vergleicht diese Struktur mit den assoziativen Feldern (arrays) in PHP und schreibt: |
|
"Flüchtig betrachtet ist ein Key Value Store erst einmal nichts weiter als ein assoziatives Array, bei dem der Key der Index des Arrayeintrags ist. Daher kann man sagen, dass auch die PHP-eigenen assoziativen Arrays durchaus als Key Value Store funktionieren: |
|
|
|
$autohaus["id:1"]='Meier" |
|
$autohaus["id:2"]=array("name":"Müller", "stadt":"Berlin") |
|
echo "Autohaus 1: ".$autohaus["id:1"] -> Meier |
|
echo "Autohaus 2 ist in ".$autohaus["id:2"]["stadt"] -> Berlin |
|
|
|
Genau diesen Ansatz verfolgen alle Key Value Stores. Daten werden gespeichert und anhand des Keys wieder abgerufen." [Kurowski 2012, Kapitel 4 (E-Book)] |
|
Was sind assoziative Felder (arrays) in PHP? |
|
Bei "normalen" Feldern (arrays) werden die einzelnen Einträge über eine automatisch vergebene laufende Nummer angesprochen. So führt $gew = array(87.5, 88.3, 90.1, 89.6, 87.4) zu einem Feld (z.B. mit den Ergebnissen der morgendlichen Gewichtsmessung), dessen Elemente automatisch durchnummeriert sind, beginnend bei 0. |
|
Assoziative Felder dagegen enthalten eine eindeutige Schlüsselbezeichnung ("key"), durch die die Elemente angesprochen werden. Beispiel: |
|
$gew = array("Montag"=>87.5, "Dienstag"=>88.3, "Mittwoch"=>90.1, "Donnerstag"=>89.6, "Freitag"=>87.4). |
|
Key und Value: Die Funktion array() macht $gew zu einem Feld mit Einträgen, die aus drei Elementen bestehen. Dem Schlüssel (Key), dem zugehörigen Wert (Value) und dem Operator "=>". Zu der Frage, ob dieser Key im datentechnischen Sinn wirklich ein Schlüssel ist, vgl. unten. |
|
Datentechnisch (im klassischen Sinn) liegen damit Attributsbezeichnungen und Attributsausprägungen vor und damit - im Hintergrund - Realweltphänomene (Objekte, Beziehungen, ...), die beschrieben werden. |
|
|
|

|
|
|
Abbildung 20.2-2: |
Das Key/Value-Konzept |
|
|
|
20.2.10 Key/Value – Datenbanken |
|
Obige Key/Value – Werte werden dann in datenverwaltenden Systemen gespeichert, verarbeitet und abgerufen. Speichern und Abrufen sind dann auch die Hauptfunktionen dieser Systeme. Viel mehr ist da auch nicht, hier wird programmiert. |
Hauptfunktionen |
In Redis werden die Einträge mit SET getätigt und die Daten mit GET abgerufen [Kurowski 2012, Kapitel 4]: |
|
>SET meinAuto Skoda Superb -> "OK"
|
|
>GET meinAuto -> Skoda Superb
|
|
Die Bezeichnung "meinAuto" ist der Key (eigentlich: Attributsbezeichnung) und "Skoda Superb" der Wert, d.h. die Attributsausprägung. |
|
Die Datentypen können bei einem solchen System, das doch recht einfache Datenstrukturen anbietet, durchaus vielfältig sein. Redis z.B. kennt integer, string, hash, list und (sorted) set [Kurowski 2012, Kapitel 4]. Eine besondere Rolle spielt bei diesem System der Datentyp Hash. Die Daten werden anhand eines Keys in einer "Hashtable" [Kurowski 2012, Kapitel 4] verwaltet. |
Datentypen |
Schlüssel, Zugriffe, Verarbeitung |
|
Unter einem Schlüssel im obigen Sinn kann also nur genau ein Wert (eine Attributsausprägung, ...) abgelegt werden. Dieser kann jede Art von Zeichen enthalten. Mehr zum möglichen Aufbau dieser Schlüssel findet sich in [Kurowski 2012, Kapitel 4]. Auch die Abfrage kann nur über diesen Schlüssel erfolgen, was die Situation für Auswertungen natürlich erschwert. Da verwundert es nicht, wenn einzelne Systeme weitere Zugriffsmöglichkeiten anbieten. Wolff et al. beschreiben für Riak, dass es neben der Abfrage nach Schlüsseln auch sekundäre Indizes gibt. Das ermöglicht den Zugriff nicht nur über den Schlüssel, sondern über andere Attribute [Wolff, Nitschinger und Trelle 2014, Pos. 396]. |
Weitere Zugriffsmöglichkeiten |
Der Einbau semantisch begründeter Beziehungen, wie bei relationalen Datenbanken, findet hier nicht statt. Es gibt also keine relationalen Verknüpfungen [Edlich, Friedland, Hampe u.a. 2011, S. 151] [Trelle 2014, S. 3]. |
|
Eine wie auch immer geartete Verarbeitung der Daten ist direkt nicht vorgesehen. Sie wird mit MapReduce (vgl. Abschnitt 20.2.6) realisiert, das für solche dann typischerweise im Netz verteilten Daten konzipiert wurde [Wartala 2012, S. 17]. |
|
Einfache Datenstruktur |
|
Diese Datenstruktur ist recht einfach. Die Schemabildung (Modellierung) und die logische Datenstruktur fällt auf das Elementarste zurück: Ohne die Zuweisung einer identifizierenden Information zu einer beschreibenden (Attributsbezeichnung Personalnummer zur Nummer selbst) geht es einfach nicht. |
|
Allerdings können oftmals die Schlüssel in Namensräume und Datenbanken aufgeteilt werden, so dass die Daten wenigstens ein Stück weit gruppiert werden. |
|
Eine solche Datenstruktur bedeutet, dass die Struktur und Semantik des Anwendungsbereichs in den Daten so gut wie nicht repräsentiert ist. Lediglich der elementare Zusammenhang zwischen beschreibender und identifizierender Information liegt vor und - sozusagen im Hintergrund - der Bezug auf bestimmte Informationsträger des Anwendungsbereichs. Der ganze Rest muss von der Anwendungssoftware geleistet werden. Dies ist eine ganz andere Vorgehensweise als in der semantischen, relationalen oder objektorientierten Modellierung. |
Weitgehend semantikfrei |
Vorteile |
|
Ein großer Vorteil dieser Art der Datenspeicherung ist, dass verteilte Datenhaltung und Skalierbarkeit leicht zu realisieren sind [Wolff, Nitschinger und Trelle 2014]. Von daher ist auch der Druck in Richtung Verzicht auf Verknüpfungen zu verstehen. Verknüpfungen über Server hinweg würden die Skalierbarkeit erschweren. Insgesamt können als Motiv für eine solche Verwaltung von Daten die riesigen Datenmengen des Internet und die Notwendigkeit der schnellen Reaktionszeit gesehen werden. |
Motive |
Für eine vertiefte Betrachtung der verschiedenen Ausprägungen dieses Systemtyps vgl. [Wolff et al. 2013]. |
|
Beispiele |
|
Edlich et al. nennen folgende Beispiele: Redis, Chordless, Riak, Membase, Voldemort, Azure Table Store, Tokyo Cabinet, BerkeleyDB, Scalaris, GT.M [Edlich, Friedland, Hampe u.a. 2011, S. 151]. |
|
20.2.11 Graphendatenbanken |
|
Die Begriffe Graph und Netzwerk bedeuten eine vernetzte Struktur. In einer solchen gibt es Knoten und Beziehungen zwischen diesen. Bei Netzwerken können diese Beziehungen mit Werten versehen sein. Vgl. für eine Einführung in die Graphentheorie [Kastens und Kleine Büning 2008, Kapitel 5], [Gumm und Sommer 2011, Abschnitt 4.9]. |
|
Bei Graphendatenbanken liegen ebenfalls Knoten und Beziehungen vor, die hier aber beide Eigenschaften haben können und zwar als Key/Value-Paare. Das wirklich hervorstechende Merkmal von Graphendatenbanken ist, dass sie ein effizientes "Durchqueren" des Graphen/Netzwerks entlang der Beziehungen erlauben [Perkins, Redmond und Wilson 2018, 286-289] |
|
Man stelle sich als Knoten eine Präsentation im SocialWeb vor und als Verbindung eine Beziehung, die "mag ich" ausdrückt. Oder, mit Bezug auf die Weltwirtschaft, die einzelnen Nationalstaaten als Knoten und die Ein- und Ausfuhren zwischen diesen als Beziehungen. Das ist eigentlich ein altes Thema. Der Verfasser dieses Textes hat bereits 1983 soziometrische Netzwerke und v.a. Welthandelsnetzwerke untersucht und Programme für deren Erfassung, Verarbeitung und graphische Darstellung geschrieben [Staud 1983]. Das Thema hat aber durch die weltweite Vernetzung und die Internet- bzw. SocialMedia- Aktivitäten inzwischen eine sehr viel größere Bedeutung gewonnen. |
Beispiele |
Graphen und Netzwerke sind in den Relationen der relationalen Theorie nur schwer abbildbar, v.a., wenn die Zeiten für Zugriff und Auswertung kurz sein müssen und der Datenbestand groß ist. Deshalb bedarf es eigener Lösungen, abseits der klassischen Datenbanktechnologie. Während der Verfasser 1983 noch die Lösung selbst programmieren musste und v.a. mit dem Problem zu kämpfen hatte, Netzwerke zwischen 100 Nationalökonomien mit der damaligen Hardware zu verwalten, gibt es heute entsprechende datenverwaltende Systeme, die Beziehungsgeflechte mit Millionen Verknüpfungen verwalten können. Die dabei entstehenden Datenbestände werden in der einschlägigen Literatur Graphendatenbanken genannt. Die aktuelle Situation beschreiben Wolff et al. wie folgt: |
Netzwerke |
"Graphendatenbanken sind vor allem auf die effiziente Speicherung von komplexen, vernetzten Domänen ausgerichtet. In den Graphen sind die Entitäten als Knoten durch getypte Kanten miteinander verbunden. Beide können beliebige Attribute enthalten." [Wolff, Nitschinger und Trelle 2014] |
|
Anmerkung: Entität steht für Informationsträger, Domäne für Anwendungsbereich (vom. engl. domain). |
|
Datenmodell, Schema |
|
Die Modellvorstellung ist also die eines Graphen (gerichtet oder ungerichtet) oder auch Netzwerks (vgl. für Beispiele hierzu [Staud 1983]) und dessen Repräsentation in der sog. Adjazenzmatrix (Nachbarschaftsmatrix), der Matrix mit den Beziehungswerten. |
|
Anwendungsbereiche |
|
Anwendungsbereiche sind neben den schon erwähnten sozialen Netzen auch sonstige Empfehlungssysteme, die Bild- und Textanalyse, die Wissensrepräsentation, das Semantic Web, Linked Open Data bis zu Geoinformationssystemen, einfach alle Anwendungsbereiche, bei denen die zu verwaltende Information nicht nur aus einzelnen Datensätzen besteht, sondern bei denen auch verknüpfende Information vorliegt und erfasst wird, bzw. im Mittelpunkt steht. Bei all diesen Anwendungen besteht die gesuchte Information nicht mehr länger nur aus einzelnen, zur Suchanfrage passenden Datensätzen, sondern aus Informationen über die Art und Weise der Verknüpfungen dieser Datensätze untereinander" (vgl. auch [Edlich, Friedland, Hampe u.a. 2011, S. 217]). |
|
Beispiele |
|
Beispiele sind Neo4j und SonesDB. Neo4j ist beschrieben in [Wolff et al. 2013, Kapitel 2]. |
|
20.2.12 Dokumentendatenbanken |
|
Was ist ein Dokument? |
|
Das Grundkonzept des Schemas (Datenmodells) sind hier sog. Dokumente. Stellen wir uns für den Anfang ein solches als einen einzelnen Datensatz im Sinne der relationalen Datenbanken vor. Die einzelnen Felder enthalten meist die Ausprägungen von Attributen (hier Werte genannt), wie gewohnt. Einzelne können aber auch Texte enthalten oder andere Informationsarten wie Arrays und eingebettete Dokumente (so bei MongoDB). Außerdem können unterschiedliche Informationsträger eine unterschiedliche Felder-Zusammensetzung haben. Die Sicht der Informatik ist wie folgt: |
Für zahlreiche Beispiele vgl. [Staud 1991, Kapitel 7]. Damals
nannte man sie Faktendatenbanken. |
Ein Dokument kann als eine geordnete Liste von Key/Value-Paaren gesehen werden (zu Key/Value-Paaren vgl. Abschnitt 20.2.9). |
|
Es werden hier also nicht nur einzelne Key/Value-Paare verwaltet, wie bei (den meisten) Key/Value-Datenbanken, sondern semantisch begründete Zusammenstellungen, die dem entsprechen, was man ansonsten Tupel (und dann später Datensatz) nennt. |
Bezugspunkt für Objekte |
Dokumente beziehen sich auf bestimmte Informationsträger, die sie beschreiben. Dies können Unternehmen, Personen, Geschäftspartner, usw. sein, einfach alles, was identifiziert (hier durch ein Attribut mit der Endung "id" gekennzeichnet) und durch weitere Attribute ("key/values") beschrieben wird. |
|
Bei CouchDB (einem wichtigen Vertreter dieses Systemtyps) werden die Datendokumente im JSON-Format (vgl. unten) gespeichert. Auch alle Arten binärer Daten (Bilder, PDF-Dateien, HTML-Dateien, CSS-Dateien, MP3-Dateien) sowie virtuelle Dokumente (entsprechend den Views der relationalen Datenbanken) können mit den Dokumenten abgelegt werden [Gull 2011, S. 73f]. In CouchDB erfolgt die Zuordnung über ein Attribut _attachements. |
|
Im Unterschied zu Datensätzen (einer Datei, bzw. Tupeln einer Relation), die ja alle denselben Aufbau haben, können Dokumente strukturell verschieden sein (wie bei den Key/Value-Datenbanken schon vorgestellt). Dies wird hier als Vorteil gesehen. Angenommen, die Dokumente beschreiben Unternehmen (für eine Wirtschaftsdatenbank). Dann ist die Gesamtzahl der Key/Value - Paare evtl. 200, verschiedene Unternehmen können aber unterschiedlich viele haben. Werden z.B. auch Tochtergesellschaften durch 10 Key/Value - Paare beschrieben, dann haben Unternehmen ohne solche auch keine entsprechenden Felder/Feldeinträge. |
Strukturell unterschiedlich |
Dies ist tatsächlich ein altes Problem, es wurde auch immer gelöst, vgl. die Faktendatenbanken früherer Zeiten, heute wird es von der NoSQL-Bewegung thematisiert. Denn natürlich haben die großen Internetanbieter - v.a. die aus dem Social Web - eine Unmenge solcher Daten gespeichert ("Profile", uw.) und wollen sie verarbeiten. Beispiele für Dokumente dieses Typs finden sich in [Trelle 2014, S. 13]. |
|
Etwas genauer lassen sich die Unterschiede zwischen Dokumenten (in der NoSQL-Fassung) und Tupeln (Datensätzen) der relationalen Theorie so beschreiben: |
Unterschiede |
(1) Unterschiedliche Anzahl von Key/Value-Paaren bei den Dokumenten. |
|
Dem entspricht bei relationalen Datenbanken eine unterschiedliche Attributzusammensetzung der Tupel (Datensätze). In der relationalen Theorie wird dies durch eine Generalisierung / Spezialisierung beseitigt und es entstehen mehrere verknüpfte Relationen (vgl. [Staud 2015, Abschnitt 14.1]). Zusammen bleiben da nur die Datensätze, die genau denselben Aufbau haben. |
|
Dieser Verzicht auf einen einheitlichen Aufbau der Dokumente führt dazu, dass die Feldbezeichnungen ("Keys") bei jedem Dokument/bei jedem Feld (Key) mitgeführt werden müssen. |
|
Zur Erinnerung: In den sequenziellen Dateien (vgl. [Staud 2015, Abschnitt 21.3]), die den Relationen zugrunde liegen, wird die Bezeichnung der Felder (der Attribute) nur am Dateianfang angegeben, danach ist sie nicht mehr nötig. |
|
(2) Eingebettete Dokumente |
|
Darunter wird verstanden, dass in einem Wert (ein Wert in einem Key/Value-Paar) ein ganzes Dokument erfasst wird. Z.B. also bei obigen Dokumenten zu einem Unternehmen eine ganze Unternehmensbeschreibung für den "Key" (das Feld) Tochtergesellschaft. Dies würde in einem relationalen Datenmodell zu einer eigenen Relation führen, die beiden Relationen wären durch Schlüssel/Fremdschlüssel verknüpft. |
|
(3) Weitere Informationsarten in den Werten (Key/Values) |
|
Also z.B. die Rede des Vorstandsvorsitzenden von der letzten Hauptversammlung als BLOB (Binary Lage Object). Diese würden in relationalen Datenbanken zu eigenen Relationen führen und über Attribute mit der Ausgangsrelation verknüpft werden. |
|
Bei all diesen Punkten verzichtet die NoSQL-Lösung auf Komplexität (z.B. auf Verknüpfungen). Dies vereinfacht das Datenmodell und den Datenbestand. Er kann dann z.B. leichter (auch horizontal) skaliert werden. |
|
JSON |
|
Wie oben schon ausgeführt, sind Dokumente hier als JSON-Datenstrukturen realisiert. JSON bedeutet JavaScript Object Notation. Es ist ein leichtgewichtiges Datenaustauschformat (www.json.org), leicht les- und schreibbar für Menschen wie Programme (ebenda), das auf einer Untermenge der JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 beruht. Betont wird sein von formalen Sprachen unabhängiges Textformat, seine Syntax ist bei der "C-Programmiersprachen-Familie" angesiedelt. Basiselement sind Key/Value - Paare, wie oben vorgestellt. |
Quelle:
www.json.org |
Grundlage von JSON sind zwei Strukturen: |
|
- Eine Sammlung von Key/Value - Paaren (Eigenschaften). Dies entspricht dem, was in anderen formalen Sprachen object, record, struct, dictionary, hash table, keyed list, oder associative array genannt wird.
- Eine geordnete Liste von Werten. Dies entspricht den Konzepten array, vector, list oder sequence anderer formaler Sprachen.
|
|
Dies sind, da hat die Quelle tatsächlich recht, universelle Datenstrukturen. Auch die Datensätze der üblichen Dateitechniken lassen sich da unterbringen. Es geht also zum einen um die elementare Zusammenstellung identifizierender und beschreibender Information, zum anderen um die Zusammenstellung solcher Informationen zur Beschreibung von ganzen Realweltphänomenen (Objekten, Beziehungen, usw.). Die konkrete Ausgestaltung in JSON ist wie folgt: |
Universelle Datenstrukturen |
- Objekte ("Realweltphänomene") werden als ungeordnete Menge von Key/Value-Paaren gesehen. Eine Objektbeschreibung beginnt und endet mit einer geschweiften Klammer. Nach der Objektbezeichnung folgt ein Doppelpunkt, danach die Key/Value-Paare, jeweils durch ein Komma getrennt.
- Ein array ist eine sortierte Sammlung von Werten. Er beginnt und endet mit einer eckigen Klammer. Die Werte sind durch Kommata getrennt.
- Datentypen sind der Nullwert (null), Boolean (true, false), Ziffern, Zeichenketten (in Anführungszeichen), die oben angeführten arrays und Objekte.
- Eine Zeichenkette ist eine Folge von Unicode-Zeichen, die in doppelten Anführungszeichen stehen.
- Ein Buchstabe wird als single character string repräsentiert
|
|
Hier ein Beispiel aus [Gull 2012, S. 299], wo sich zahlreiche weitere Beispiele finden. Die Objekte dieses Beispiels sind Städte und ihre Verkehrsinfrastruktur: |
Vgl. zu folgendem auch die Syntaxdiagramme in der Quelle |
{
|
|
"_id": "city_münchen",
|
|
"_rev": "2-54a357f5e0172cb2c35b4b2ea88fa366",
|
|
"country": "Deutschland",
|
|
"cityName": "München",
|
|
"subName": "U-Bahn",
|
|
"memos": "Wurde zur Olympiade in den 1970ern eröffnet.",
|
|
"type": "city",
|
|
"created_at": "2011-05-08T17:11:09.007Z"
|
|
}
|
|
Das binäre Format von JSON wird BSON (Binary JSON) genannt. |
|
Ist ein "Key" ein Schlüssel? |
|
Jetzt wird es Zeit, den Begriff key in key/value zu hinterfragen. Bezogen auf ein Objekt (mit einer identifizierenden und üblicherweise mehreren beschreibenden Informationen) ist er nicht sinnvoll, da außer dem Schlüssel (der id) meist kein weiteres identifizierendes Attribut vorhanden ist. Besser wäre, wie es in einigen wenigen Quellen auch getan wird, von name/value pairs zu sprechen, denn es geht ja nur um die Bezeichnung der Eigenschaft (Bezeichnung des Attributs). Da sich aber in der einschlägigen Literatur der Begriff key/value durchgesetzt hat, soll er auch hier verwendet werden. |
|
Betrachtet man, wie bei den Key/Value-Datenbanken, die einzelnen Eigenschaften isoliert (was ja eigentlich nicht sinnvoll ist, denn eine Objektbeschreibung benötigt mindestens zwei Key/Values), erscheinen die Attributbezeichnungen als Schlüssel. Im obigen Beispiel: country für sich betrachtet ist identifizierend - für Staaten - nicht für Städte und ihre Verkehrseinrichtungen. |
|
Schlüssel, Id |
|
Jedes Dokument hat (auch hier) einen eindeutigen Schlüssel, in MongoDB gibt es dafür einen Datentyp ObjectId [Trelle 2014, S. 7]. Er wird im Feld _id verwaltet. Schlüssel müssen hier natürlich ausgefeilter sein als in relationalen Datenbanken. Zum Beispiel besteht bei MongoDB die ObjectId aus 12 Bytes mit folgender Bedeutung: Zeitstempel mit 4 Bytes, Maschine mit 3 Bytes, PID mit zwei Bytes, Zähler mit 3 Bytes. Der Zeitstempel gibt die Sekunden seit dem 1.1.1970 an [Trelle 2014, S. 36]. |
|
Erläuterung: |
|
Maschine: Computer, auf dem die ID erzeugt wurde. Hashwert des Hostnamens. |
|
PID: Identifikation des laufenden Prozesses. |
|
Zähler: einfacher Zähler, der inkrementiert wird. "Damit können von einem Prozess ... 16 MB ... Dokumente pro Sekunde eingefügt werden, bevor es zu Kollissionen kommt." [Trelle 2014, S. 36] |
|
Auf dem Primärschlüssel liegt ein Index [Trelle 2014, S. 37], so dass Suchvorgänge wesentlich beschleunigt werden. |
Indexierung |
Versionierung |
|
Das Ändern von Daten läuft hier wie folgt ab (am Beispiel CouchDB): Ist ein Feld zu ändern, wird das gesamte Dokument geladen und verändert. Dann wird das gesamte Dokument als neue Version abgespeichert [Gull 2011, S. 72]. Deshalb erhalten Dokumente eine Revisions-ID, die bei jedem Update verändert wird, so dass ein gezieltes Auffinden der Änderungen ermöglicht wird. |
Ändern von Daten |
Die Kennzeichnung der Versionen ist (bei CouchDB) wie folgt: Am Anfang steht eine fortlaufende Nummer, woraus erkennbar ist, wie oft das Dokument gespeichert wurde. Es folgt ein Bindestrich und nach diesem ein von CoachDB berechneter MD5-Hashwert [Gull 2011, S. 73]. MD5 bedeutet Message-Digest Algorithm 5. Dieser Hashwert ist eine Prüfsumme mit der Länge 128 Bit, die aus einer beliebigen Zeichenfolge erzeugt werden kann [Gull 2011, S. 339]. |
Kennzeichnen von Versionen |
Mehrfachzugriffe bewältigen |
|
Das klassische Vorgehen bei Mehrfachzugriffen ist, dass ein Datensatz gesperrt ist, solange der Zugriff erfolgt. Dies ist bei verteilten Daten und der gleichzeitigen Forderung nach möglichst sofortiger Anfragebeantwortung nicht möglich. Hier mussten also andere Lösungen gefunden werden. Eine davon wird MVCC(Multi-Version-Concurrency-Control) genannt. Sie kontrolliert konkurrierende Zugriffe auf eine Datenbank und führt sie effizient aus und zwar so, dass normalerweise keine Blockaden bei den einzelnen Zugriffen auftreten. Außerdem muss die Datenbankkonsistenz gesichert werden. Um die Effizienzforderung zu erfüllen, müssen Transaktionen nicht warten, bis Datenbankobjekte verfügbar sind. Dazu werden verschiedene versionierte Objekte im Speicher vorgehalten und den jeweiligen Transaktionen angeboten [Gull 211, S. 340]. Auf diese Weise werden lesende Zugriffe niemals blockiert. Allerdings geht dies zu Lasten des Speicherplatzes, da viele verschiedene Versionen eines Objekts vorgehalten werden müssen. |
MVCC |
Wieso MVCC? |
|
Diese Datenbanksysteme übertragen die Daten zwischen den Rechnerknoten mit dem HTTP-Protokoll. So auch CouchDB. Das HTTP-Protokoll ist zustandslos (stateless), was bedeutet, dass eine Übertragung wie folgt realisiert wird: Es wird eine Anfrage (request) an den Server gesendet, die Netzwerkverbindung wird geöffnet, die Daten werden gesendet und/oder empfangen, die Verbindung wieder geschlossen und der Server verliert die Informationen zur Anfrage wieder. D.h. der Client packt alle notwendigen Informationen in diese eine Anfrage [Gull 2011, S. 30]. Dadurch wird die Kontrolle der Daten dem Datenbankserver entzogen, sie liegt bei der Anwendung und ein Verfahren wie MVCC muss für die Abstimmung der Zugriffe sorgen. |
|
Datenmodell, Schema |
|
Damit ergibt sich, gegenüber den relationalen Datenbanken, eine wesentlich veränderte Struktur des Datenmodells (Schemas). Elementarer Bestandteil sind die Dokumente, mit der Flexibilität bzgl. ihres Aufbaus (unterschiedliche Key/Value – Paare, usw.). Eine weitergehende Strukturierung erfolgt, ähnlich den Key/Value - Datenbanken, durch Collections. Dies sind Gruppierungen von Dokumenten nach inhaltlichen / fachlichen Gesichtspunkten, die beim Umgang mit den Daten Bedeutung haben. Z.B. können in MongoDB innerhalb einer Abfrage nur Dokumente aus einer Collection durchsucht und zurückgeliefert werden [Trelle 2014, S. 93]. Direkt vom System her kommen zum Datenmodell noch hinzu die Versionen von Dokumenten. |
|
Das, was man als relationale Verknüpfung kennt, gibt es bei diesem Datenbanksystemtyp nicht. Es gibt aber Referenzen auf Objekte. Diese können manuell oder mittels sogenannter DBRef-Verweise verwaltet werden. Verwendet man DBRefs, wird neben der ObjektId des referenzierten Dokuments auch der Name der Collection und ggf. sogar der Name der Datenbank gespeichert. Ein Beispiel: |
Verknüpfungen zwischen Dokumenten (Referenzen) |
{$ref: <collectionName>, $id: <ObjectId>, $db: <dbName>} [Trelle 2014, S. 39]. |
|
Somit kann zumindest ein Stück weit die Beziehungssemantik von Daten erfasst werden. |
|
Ein Datenmodell wie dieses erlaubt ein Vorgehen, wie es Edlich et al. für MongoDB beschreiben: |
Beispiel MongoDB |
"Das Schema wird mit Einfügen eines Dokuments zur Laufzeit erzeugt." [Edlich, Friedland, Hampe u.a. 2011, S. 133] |
|
Und, so kann man ergänzen, wird mit jedem abweichenden Dokument verändert. |
|
Auf einen wichtigen Nachteil dieser Schemaausgestaltung und -flexibilität weist Trelle hin: Es gibt keine Transaktionen, die mehr als ein Dokument umfassen und selbst bei Operationen auf nur einem Dokument ist kein explizites Rollback möglich [Trelle 2014, S. 7]. |
|
Beispiele |
|
Apache CouchDB, MongoDB, Lotus Notes [Gull 2011, S. 19]. |
|
20.2.13 Spaltenorientierte Datenbanken |
|
Eine andere Zielsetzung als obige NoSQL-Datenbanken hat die in diesem Abschnitt vorgestellte Architektur. Bei ihr geht es darum, durch eine andere Art der Speicherung der Tabellen (Relationen) relationaler Datenbanken bestimmte Auswertungen schneller ausführen zu können. |
|
Zeilenorientiert - Spaltenorientiert |
|
Für Relationen gibt es die konzeptionelle Vorstellung einer Tabelle, die dann durch einige Festlegungen ("flat table", ...) zur Relation wird (vgl. die Kapitel 4 – 13 in [Staud 2015]). Dabei stehen die Attribute nebeneinander und beschreiben die Tupel. In jedem Tupel stehen dann die Attributsausprägungen genauso nebeneinander. Auch bei der physischen Datenorganisation relationaler Datenbanken ist dies dann so. Aus Tupeln werden Datensätze, am Anfang der Datei ist der Dateikopf mit den Attributsbezeichnungen, Datentypen, usw., dann folgen die Datensätze, einer nach dem anderen, jeweils Ausprägung nach Ausprägung. Deshalb werden diese Datenbanken als zeilenorientiert bezeichnet. |
Zeilenorientierung |
Diese "Zeilenorientierung" ist gut im Sinne sparsamer Datenzugriffe, wenn mehrere Attribute einer Relation abgefragt werden müssen, z.B. die Namen, Vornamen und Gehälter der Angestellten. Sprünge beim Lese- oder Schreibzugriff gibt es dann im Wesentlichen nur, wenn von Tupel zu Tupel weitergegangen wird. Hat man nun aber Abfragen, bei denen ein bestimmtes Attribut über sehr viele Tupel, also eine Ausprägung über sehr viele Datensätze, abgefragt wird, ist diese Anordnung hemmend. Von jedem Datensatz wird ja nur eine Ausprägung gelesen, dann muss die Abfrage zum nächsten Datensatz springen. Dies kostet Zeit. Ein wirkliches Problem ist dies angesichts der immer besser gewordenen Zugriffsgeschwindigkeiten externer Speicher aber nur bei sehr großen Datenmengen. |
|
Für solche Situationen wurden die spaltenorientierten Datenbanksysteme und Datenbankengeschaffen. Hier werden die Attributsausprägungen eines Attributs mehrerer Tupel (sozusagen) hintereinandergeschrieben. Jede Spalte kann dabei in einer eigenen Datei liegen. Die Ausprägungen eines Attributs liegen hier also hintereinander, über die Tupel hinweg. Hierzu ein Beispiel: |
Spaltenorientierung |
Es soll eine Datenbank mit Kundendaten angelegt werden. Die Attribute sind KuNr (Kundenummer), KuName (Kundenname), Ort und Umsatz. Das führt in relationalen Datenbanken zur folgenden konzeptionellen Tabellendarstellung: |
|
KUNDEN |
|
#KuNr |
KuName |
Ort |
Umsatz |
1001 |
Schmidt |
Berlin |
5000 |
1002 |
Koch |
Stuttgart |
3000 |
1003 |
Widmer |
Köln |
7000 |
... |
|
|
|
| |
Zeilenorientiert
|
|
Die klassische Lösung in relationalen Datenbanken, die auf der physischen Ebene zu evtl. indexierten sequentiellen Dateien führt, ist wie folgt: Alle Datenwerte einer Zeile (Attributsausprägungen) werden aneinandergefügt und anschließend folgt die nächste Zeile. Somit entsteht aus dem obigen Beispiel eine "Tupelfolge" mit folgendem Aufbau: |
|
1001, Schmidt, Berlin, 5000; 1002, Koch, Stuttgart, 3000; 1003, Widmer, Köln, 7000; ... |
Zeilen hintereinander |
Der Strichpunkt wurde als Trenner zwischen den Tupelwerten genommen. |
|
Und nun spaltenorientiert |
|
Eine spaltenorientierte Datenbank hingegen legt die Ausprägungen eines Attributs in der entsprechenden Datei über alle Tupel hinweg hintereinander. Mit dem obigen Beispiel: |
|
1001,1002,1003; Schmidt, Koch, Widmer; Berlin, Stuttgart, Köln; 5000, 3000, 7000; ... |
Spalten hintereinander |
Die konzeptionelle Vorstellung ist die einer Zerlegung der Relation: |
|
KUNDEN-Name |
|
#KuNr |
KuName |
1001 |
Schmidt |
1002 |
Koch |
1003 |
Widmer |
... |
|
| |
KUNDEN-Ort
|
|
#KuNr |
Ort |
1001 |
Berlin |
1002 |
Stuttgart |
1003 |
Köln |
... |
|
| |
KUNDEN-Umsatz
|
|
#KuNr |
Umsatz |
1001 |
5000 |
1002 |
3000 |
1003 |
7000 |
... |
|
| |
Entscheidend ist aber nicht diese, sondern die damit einhergehende veränderte physische Struktur.
|
|
Hat man Auswertungen, die zahlreiche Attributsausprägungen eines Attributs verarbeiten (hier z.B. der Durchschnittsumsatz aller Kunden; eine Auszählung, wieviele Kunden in den einzelnen Städten sind), müssen nicht alle Zeilen, sondern nur die Spalten, welche für die Auswertung relevant sind, durchsucht werden. Damit erhofft man sich vor allem folgende Vorteile: |
Vorteile der spaltenorientierten Speicherung |
- Die für Auswertungen in einem Data Warehouse benötigten Auswahlprozesse können, wenn sie auf einem einzelnen Attribut basieren, schneller realisiert werden.
- Aggregate (gespeicherte aggregierte Werte: z.B., ausgehend von Tagesdaten, die von Wochen, Monaten, Jahren) können eingespart werden, da die aggregierten Werte bei Bedarf in Realzeit berechnet werden.
- Bessere Komprimierbarkeit, da die Spalten homogenere Daten als Tupeldaten haben. Vgl. unten.
- Evtl. Verzicht auf Indexierung, da diese Speicherungstechnik die Effizienz der Abfragen steigert.
|
|
Diesen Vorteilen steht der Nachteil gegenüber, dass das Einfügen von Tupeln aufwendiger ist. Ebenso die Durchführung bestimmter Abfragen, z.B. wenn viele oder alle Attribute der Tupel benötigt werden. Dann muss bei dieser Speicherungsform deutlich mehr „gesprungen“ werden als in der zeilenorientierten. |
Nachteil |
Neben dem schnelleren Zugriff ist der Wunsch nach effizienterer Komprimierung ein Motiv, denn die spaltenorientierte Speicherung eignet sich besonders gut für Komprimierungsmethoden. Der Grund liegt darin, dass Daten desselben Typs (Attributsausprägungen eines Attributs) auf dem Speichermedium in aufeinander folgenden Abschnitten gespeichert werden. Wenn es sich beim jeweiligen Attribut nicht um einen Schlüssel handelt, liegen sogar viele gleiche Attributsausprägungen vor. |
Hauptmotiv: große Datenmengen |
Als Komprimierungsmethode nennen [Plattner und Zeier 2011] die Light-Weight-Compression. Die Vorgehensweise ist recht einfach, so können mehrfach vorkommende Werte durch Variablen ersetzt werden, die in einem Wörterbuch gepflegt werden. Mithilfe dieses Wörterbuches können sie wieder in ihre ursprünglichen Werte übersetzt werden. Bei identischen Werten, die direkt aufeinander folgen, können diese als Sequenzlauflängen codiert abgelegt werden. |
|
Ein weiteres Entwurfsziel spaltenorientierter Datenbanken ist die Erleichterung der horizontalen Skalierbarkeit. Damit ist die Möglichkeit gemeint, den Datenbestand und seine Verarbeitung auf eine große Anzahl von Clustern zu verteilen (vgl. [Staud 2015, Abschnitt 24.5.6]). |
Horizontale Skalierbarkeit |
Zusammengefasst kann mit [Plattner und Zeiher 2011] festgehalten werden, dass spaltenorientierte Datenbanken für analytische Systeme mit sehr vielen Lesevorgängen optimiert sind, während zeilenorientierte Datenbanken für operative Systeme mit sehr vielen Schreibvorgängen entwickelt wurden. |
|
[Plattner und Zeiher 2011] empfehlen für moderne Datenbanksysteme beides, Zeilen- und Spaltenorientierung (hybride Technik). Durch eine solche optimale Mischform sehen sie Performanceverbesserungen von bis zu 400% gegenüber einer reinen Zeilen- oder Spaltenorientierung. |
Hybride Technik |
|
|
| | | | | | | | | | | | | | | | | | | |
| |