Aufbewahrung von Daten

»Wenn man nur mal eben schnell eine Tabelle braucht, die nicht mehr als 7 Spalten hat und die man bequem mit anderen Leuten zusammen bearbeiten kann, dann kann man übrigens auch einfach den Googlekalender nehmen.«

Kommentator »Blog zum Gärtner«, riesenmaschine.de

Manche Programme haben keine hohen Anforderungen an die Aufbewahrung von Daten. Wenn Sie beispielsweise eine Chatanwendung schreiben, müssen Sie sich nur über Konfigurationsdateien und gegebenenfalls Logging von Chats Gedanken machen. lm Großen und Ganzen ist die Kernaufgabe eines Chatprogramms nur, Nachrichten zu empfangen, darzustellen und selbst zu versenden.

Viele Spiele brauchen keine ausgefeilte Datenhaltung. Grafiken und Spielskripte werden mitgeliefert und die Spielstände können leicht in kleinen Dateien abgespeichert werden. Spieleprogrammierer müssen sich selten um Datenaustausch mit anderen Programmen oder geeignete Formate für die Langzeitarchivierung sorgen.

Auch die Entwickler von Texteditoren sind an dieser Stelle fein raus: Die Benutzer öffnen Dateien, bearbeiten sie und speichern sie, der Editor muss keine Datenbank führen. Der Benutzer ist in diesem Fall vollständig selbst dafür verantwortlich, wo und wie er seine Daten aufbewahren möchte.

In vielen Bereichen sieht es aber anders aus, und als Entwickler müssen Sie sich Gedanken darum machen, wie Sie Daten verwalten, durchsuchbar machen und möglicherweise archivieren. Manche Anwendungen wie wissenschaftliche Auswertungssoftware sind ohne ihre Daten völlig nutzlos. Hier sind die Daten häufig wichtiger als das Programm, und Sie als Entwickler sind recht häufig der einzige oder einer der wenigen Benutzer - Sie sollten also die Frage der Datenaufbewahrung bei der Entwicklung gleich mitbedenken.

Wenn Sie eine Mobile-App schreiben, dann haben Sie meist ein Backend, das sich um seine Userverwaltung kümmern und - je nach Typ der Anwendung - auch Geodaten oder von Nutzem eingegebene Inhalte speichern und wiedergeben können muss. Gerade Smartphone-Apps sind derzeit eine Gelegenheit, die Probleme früherer Programmierergenerationen am eigenen Leib zu erfahren: Die Geräte sind vergleichsweise langsam und

haben wenig Speicher. Daher kann man als Entwickler nicht alle Daten einfach im RAM halten, sondern muss nicht benötigte Daten in den Flash-Speicher auslagern. Da die UMTS-Verbindung zum Backend viel langsamer ist als bei einem über DSL und WLAN angebundenen Computer, müssen Sie sich viel eher Gedanken darüber machen, welche Daten Sie zwischen Mobile-App und Backend austauschen und welche auf dem Gerät bleiben. Andererseits sollten kritische Daten auf dem Backend-Server lagern, denn Smartphones gehen recht häufig verloren. Ihre Anwenderin ist Ihnen dankbar, wenn danach nicht alles weg ist, sondern die Daten einfach auf ein neues Gerät synchronisiert werden können.

Die Entscheidung darüber, wie Sie Ihre Daten aufbewahren, müssen Sie frühzeitig treffen, und sie ist später schwer zu ändern. Es ist zwar prinzipiell möglich, eine Anwendung so zu refakturieren, dass sie ihre Daten in einer Datenbank statt in Dateien hält, aber diese Änderung kann ganz erheblichen Aufwand verursachen. Bevor Sie anfangen zu programmieren, sollten Sie sich daher über Ihre Anforderungen an die Datenhaltung Gedanken machen.

>>Die selbstgeschriebene Blog-Engine, mit der ich mehrere Blogs betreibe, verwendet keine Datenbank, weil mir Datenbanken bis heute auf diffuse Weise unangenehm sind, obwohl ich sie schon lange einsetze und auch hier gewusst hätte, wie es theoretisch ginge. Die vor Jahren leichtfertig getroffene Entscheidung >ach, das geht sicher auch mit Textdateien< habe ich seitdem oft bereut, denn natürlich sind Datenbanken eine Lösung, die für exakt diese Aufgabenstellung entwickelt wurde.«

Kathrin

Für diese Entscheidung sollte dabei nicht maßgeblich sein, wie Sie die Daten speichern (das ist ganz einfach), sondern wie Sie sie wieder abrufen wollen. Daten, die nur archiviert werden müssen, können in Dateien gespeichert werden. Aber wenn Sie die Daten flexibel durchsuchen wollen, wenn Sie Summen bilden und Datensätze filtern und verknüpfen wollen, dann sollten Sie über eine Datenbank nachdenken.

Im Großen und Ganzen gibt es drei verschiedene Verfahren, Daten zu speichern:

•    Dateien. Für kleine Projekte und für den ersten Ansatz die einfachste Lösung.

° Datenbanken. An Datenbanken kommen Sie nicht vorbei, wenn Ihr Programm m den Daten suchen oder sie analysieren soll.

•    Versionskontrollsysteme. Ein eher ungewöhnlicher Weg, Daten zu speichern. Kann aber nützlich sein, wenn sich die Inhalte häufig ändern.

Dateien

Wenn Sie nicht gerade eine reine Webanwendung mit JavaScript schreiben, kann Ihr Programm mit wenig Aufwand seine Daten in Dateien speichern und später wieder lesen.

Häufig werden Sie Daten schon in Dateien angeliefert bekommen - sei es, dass Sie CSV-Dateien mit Finanzdaten importieren sollen, um sie zu analysieren, sei es, dass Sie die

Ergebnisse wissenschaftlicher Messungen bearbeiten wollen. Aber selbst wenn Sie Daten aus dem Web beziehen oder Ihre Nutzer selbst die Daten erzeugen, können Sie sie in Dateien verstauen und später wieder einlesen.

Daten in Dateien abzulegen, hat ein paar Vorteile: Es ist einfach, egal in welcher Programmiersprache. Sie müssen sich nicht mit Datenbankverbindungen, SQL oder Versi-onskontrollsystemen auseinandersetzen. Auch die Archivierung der Daten ist kein Problem, das kann ein Backup-Programm miterledigen, wenn es Ihr System sichert. Der Datenaustausch mit anderen kann per Mail, Dropbox oder SFTP-Uploads erfolgen, auch bei sehr großen Dateien. Notfalls geht es immer noch mit einem USB-Stick.

Dem stehen aber auch ein paar Nachteile gegenüber: Eine Volltextsuche ist schnell programmiert und liefert auch schnell Ergebnisse, solange Sie nur kleine Datenbestände haben. Aber für große Dateien müssen Sie bereits eine Suchmaschine wie Lucene installieren und aus Ihrem Programm heraus ansprechen.

Wenn Sie flexible Abfragen wie »Alle Filialen mit einem Umsatz zwischen x und y Euro<< unterstützen wollen, müssen Sie die Daten einlesen und für jeden derartigen Abfragetyp Code schreiben. Und wenn Sie viele und komplexe strukturierte Suchen anbieten wollen (»Alle Messwerte, die von Gerät >Robot 183< stammen und bei denen der Messwert >Joint 3 rotation< mehr als 45° ist«), wird es aufwendig. Mit einer Datenbank ist das simpel, denn genau dafür wurden Datenbanken und SQL erfunden.

Sollen Ihre Benutzer Daten verändern können? Dann müssen Sie die Datensätze laden und die geänderten wieder in Dateien schreiben. Und dann müssen Sie sich Gedanken darüber machen, wie Sie diese Änderungen verwalten wollen. jedesmal den ganzen Datenbestand neu schreiben? Versionen führen? Auch das kann ziemlich aufwendig werden und ist in einer Datenbank oder einem Versionskomrollsystem einfacher. Und hier lauert auch gleich das Problem, das bei der Speicherung in Dateien am schwierigsten zu bewältigen ist: Wenn zwei Benutzer gleichzeitig Änderungen vornehmen, die unterschiedliche Teile derselben Datei betreffen, muss Ihr System diese Änderungen zusammenführen, ohne dass die Arbeit des einen Benutzers verloren geht. Das ist alles andere als einfach - immerhin wurden dafür eigens Versionskontrollsysteme erfunden. In einer Datenbank werden Datensätze in unterschiedlichen Tabellen (relationale Datenbanken) oder Einträgen (Document-Store Datenbanken) abgelegt, und die Datenbank sorgt dafür, dass parallele Änderungen konfliktfrei möglich sind.

Sollte Ihre Wahl auf Dateien zur Datenaufbewahrung fallen, dann müssen Sie sich für ein Format entscheiden. Derzeit sind CSV/TSV, XML, JSON oder ein freies Textformat üblich. Egal, für welches Format Sie sich entscheiden: Stellen Sie vorher sicher, dass die Daten UTF-8-codiert sind, sonst erleben Sie beim Einlesen unerfreuliche Überraschungen (siehe Kapitel 17).

Für alle Formate konstruieren wir jeweils ein Beispiel aus einem Warenwirtschaftssystem, das die Eigenschaften von zwei Artikeln in einer Datei festhalten will: einer Couch und einem Tisch.

Freie Textformate bieten volle Flexibilität: Sie entscheiden selbst, wie Sie Ihre Daten ablegen wollen. Sie können beispielsweise pro Zeile einen Datensatz schreiben. Für Logfiles und ähnliche Formate ist so eine Lagerung angemessen, denn die Logeinträge werden im laufenden Betrieb immer hinten an eine Logdatei angehängt. Das geht so schnell, dass das Programm nicht durch sein Logging aufgehalten wird. Ansonsten empfehlen wir, auf eigene Formate zu verzichten, weil Sie allen Code selbst schreiben müssen und keine Bibliotheken nutzen können, wie sie etwa für XML zur Verfügung stehen.

Ein Beispiel, bei dem verschiedene Waren durch eine Zeile mit @@item@@ getrennt werden:

@@item@@

name: couch

color: slab grey

dimensions: 200x90x70

@@item@@

name: table

color: wood

dimensions: 150xlOOx90

CSV/TSV

CSV/TSV sind Textformate, die von Tabellenkalkulationsprogrammen wie Excel importiert und exportiert werden können. Die einzelnen Zeilen sind durch Zeilenumbrüche getrennt, die Spalten durch Komma oder Semikolon (CSV) bzw. Tabs (TSV). CSV/TSV-Dateien sind ziemlich kompakt. Das Format ist eine gute Wahl, wenn Sie die Daten vor allem betrachten wollen. Sie können sich dann ersparen, selbst ein Programm zum Betrachten der Daten zu schreiben, und sie stattdessen in einem Tabellenkalkulationsprogramm öffnen.

In unserem Beispiel enthalten die erste Zeile die Namen der Spalten und die beiden folgenden die Artikel:

item;color;length;width;height couch;slab grey;200;90;70 table;wood;150;100;90

Problematisch wird es, wenn ein Datensatz die Zeilen- oder Spaltentrenner (Komma, Semikolon oder Tab) enthält. Dann müssen Sie diesen Datensatz entweder filtern oder irgendwie umcodieren, weil sonst Ihre Lesefunktionen durcheinanderkommen. Teilweise werden auch Anführungszeichen verwendet, um Spalteninhalte zusammenzuhalten, die einen Spaltentrenner enthalten, dann müssen aber die Anführungszeichen umcodiert werden.

CSV/TSV sind ungeeignet, um hierarchische Daten abzuspeichern, weil das Format ein strenges Zellenraster aus Zeilen und Spalten vorgibt, eben wie in einem Blatt einer Tabellenkalkulation. Hierarchische Daten müssten in einer Zelle eine weitere Unterteilung vornehmen können, das ist aber nicht möglich.

XML

XML ist ein her'orragendes Aufbewahrungsformat für komplexe und hierarchische Daten. Sie können ohne Weiteres einen Kunden mit Namen und Anschrift sowie allen Bestellungen in XML ablegen. Auch viele Textverarbeitungsprogramme benutzen XML, um Texte mit Formatierungen abzuspeichern. Sowohl für das Lesen als auch für das Schreiben von XML gibt es für nahezu alle Sprachen Bibliotheken, die Ihnen das Leben erleichtern. Verwenden Sie unbedingt eine solche Bibliothek, denn dann müssen Sie sich keine Gedanken machen, wie Sie < oder & abspeichern - beides Zeichen, die zur Struktur von XML gehören und daher in Nutzerdaten nicht einfach auftauchen dürfen. XML-Bibliotheken kümmern sich darum, diese Zeichen so zu maskieren, dass gültiges XML entsteht, die Zeichen aber auch nicht verloren gehen.

Unsere Möbel in XML:

<item name="couch">

<color="slab grey">

<dimensions>

<length>200</length>

cwidth>90</width>

<height>70</height>

</dimensions>

</item>

<item name="table">

<color="slab grey"> cdimensions>

<length>lSO</length>

<width>iOO</width>

<height>90</height>

</dimensions>

</item>

Im Beispiel kann man gut erkennen, dass <dimensions> ein Container ist, der die Angaben für Länge, Breite und Höhe zu einer Einheit zusammenfasst. Das ist praktisch, um die Größenangaben im Programm in einem Hash zu speichern.

Allerdings gilt auch: XML ist häufig Overkill, wenn Sie nur einfache Daten speichern möchten. Gleichzeitig bietet es für sehr komplexe Daten aber nicht die Such- und Analysefunktionen einer Datenbank. Wenn Ihnen XML angemessen erscheint, dann denken Sie zumindest kurz darüber nach, ob eine Datenbank nicht die bessere Lösung wäre.

JSON

JSON ist ein insbesondere im Web 2.0 viel verwendetes Format, das vonJavaScript abgeleitet ist. Es bietet die gleichen Möglichkeiten wie XML, hierarchische und komplexe Daten abzuspeichern, ist aber flexibler und kann zumindest aus JavaScript schneller gelesen werden. JSON wird gerne benutzt, um Daten zwischen verschiedenen Rechnern auszutauschen, ist als Speicherformat aber derzeit eher unüblich. Unser Beispiel sieht in JSON so aus:

[

{

"type" : "item", "name" : "couch", "color": "slab grey", "dimensions": { "length": 200, "width": 90, "height": 70

}

}.

{

"type" : "item", "name" : "table", "color" : "wood", "dimensions": { "length": 150, "width": 100, "height": 90

}

}

]

Wie XML kann JSON tief verschachtelte Strukturen gut repräsentieren; im Beispiel sind das Länge, Breite und Höhe, die als eigenes »Dimension«-Objekt abgespeichert werden, statt als einzelne Eigenschaften.

Es gilt wie bei XML: Wenn Sie darüber nachdenken, Ihre Daten inJSON zu speichern, dann überlegen Sie, ob eine Datenbank nicht doch angebrachter wäre. Insbesondere Document-Store-Datenbanken, die wir weiter unten vorstellen, sind für die Speicherung von JSO X ideal, denn sie speichern die Daten genau in diesem Format. Aber auch aus relationalen Datenbanken kann man leicht JSON erzeugen und für Webapplikationen vervenden.

YAML

YAML (kurz für »YAML Ain't Markup Language<<) ist ein Speicherformat, das eine Erweiterung von JSON darstellt. YAML kann Kommentare beinhalten, es erlaubt geordnete Listen und benutzerdefinierte Datentypen. Angenehm: Strings müssen nicht in Anführungszeichen eingeschlossen werden, das liest sich leichter. jede JSON-Datei ist auch eine gültige YAML-Datei, aber nicht umgekehrt. Unser Beispiel in YAML:

type: item name: couch color: slab grey

dimensions: {length: 200, width: 90, height: 70}

type: item name: table color: wood

dimensions: {length: 150, width: 100, height: 90}

Trotz guter Unterstützung durch eine Reihe von Bibliotheken für viele Sprachen ist YAML ein relativ seltenes Format.

Versionskontrollsysteme

Auch in Versionskontrollsystemen werden Dateien gelagert, man muss sich daher die gleichen Gedanken über die Formatwahl machen wie bei der Aufbewahrung im Dateisystem. Der große Vorteil beim Einsatz eines Versionskontrollsystems ist, dass die Speicherung der Daten von der Langzeitarchivierung getrennt wird und für die Archivierung ein bewährtes System zum Einsatz kommt, das Sie nicht selbst entwickeln müssen.

Versionskontrollsysteme sind als Datenspeicher-Backend eher ungewöhnlich. Sie helfen dem Entwickler nicht dabei, flexible Suchen oder Berechnungen in den Daten anzustellen. In Nischen können sie aber nützlich sein, nämlich immer dann, wenn Datensätze häufig geändert werden und alte Versionen aufbewahrt werden sollen, was in einer Datenbank zwar möglich, aber lästig ist. Beispielhafte Einsatzgebiete wären Wikis oder Blog-Engines.

Datenbanken

Über die Jahre sind ziemlich viele unterschiedliche Datenbanktypen entstanden. Viele Jahrzehnte lang waren relationale Datenbanken (zur Begriffserklärung siehe unten) die einzig relevanten - und auch heute noch denkt jeder an diesen Datenbanktyp, wenn er einfach nur von Datenbanken spricht.

In den 2000er Jahren wurden neben dem etablierten relationalen Standard noch weitere entwickelt, die unter dem Stichwort NoSQL zusammengefasst werden. Für einige Anwendungsbereiche sind sie eine interessante Alternative zu relationalen Datenbanken. Was sie vom relationalen Modell unterscheidet, erläutern wir gleich.

Suchen und Finden

Datenbanken sind nicht deswegen toll, weil man darin Daten ablegen kann, denn das geht genauso gut in Dateien. Datenbanken glänzen vielmehr durch die Flexibilität, mit der man in diesen Datenbeständen suchen kann.

Wollen Sie beispielsweise die Artikel aus einem Content-Management-System als XML-Dateien halten, dann könnten Sie die Einzeldateien entweder nach dem Entstehungszeitraum sortieren, indem Sie beispielsweise eine Verzeichnishierarchie Jahr/Monat/Tag anlegen und den genauen Zeitstempel als Dateiname verwenden. Oder Sie könnten für jeden Autor ein Verzeichnis mit seinen Beiträgen anlegen oder Mischformen zwischen Datum/Autor/Titel des Beitrags. In allen Fällen ist es ziemlich aufwendig, wenn Sie eine Suche nach einem Kriterium durchführen, das nicht in der Verzeichnishierarchie oder dem Dateinamen codiert ist, denn dann müssen Sie alle Dateien einlesen und in demjenigen XML-Feld suchen, das Ihrem Suchkriterium entspricht.

Datenbanken hingegen legen Daten strukturiert ab und erlauben Ihnen, nach allen Eigenschaften eines Datensatzes zu suchen. Sie haben die Freiheit, nach Autor zu suchen, nach Datum oder nach einer Kombination wie »Artikel, die von Johannes zwischen dem 29.1.2009 und dem 13.10.2013 geschrieben wurden«. Datenbanken können diese flexiblen Suchen sehr schnell durchführen, und noch schneller geht es, wenn Sie vorher Indizes im Datenbestand angelegt haben.

Indizes funktionieren im Grunde wie das Register eines Buchs. Wenn Sie in einem Sachbuch die Seiten suchen, auf denen ein bestimmter Begriff verwendet wird, dann lesen Sie nicht das Buch von Anfang bis Ende durch und notieren die Fundstellen, sondern Sie sehen im Schlagwortindex am Ende des Buches nach.

Wenn Sie daher Datenbanken verwenden, lohnt es sich, ein bisschen über das Thema Indizes zu lesen und für jede Eigenschaft, nach der Sie möglicherveise suchen wollen, einen Index zu definieren. Relationale Datenbanken, die wir im nächsten Abschnitt erklären, legen für Primärschlüssel automatisch einen Index an. Für alle weiteren Eigenschaften müssen Sie bei der Datenbank einen zusätzlichen Index in Auftrag geben. In NoSQL-Systemen müssen Sie meist alle Indizes explizit anlegen lassen. Indizes werden von der Datenbank ständig und automatisch aktuell gehalten: Fügen Sie neue Daten hinzu, dann werden diese auch gleich indiziert. Verändern Sie Daten, dann wird die Datenbank den entsprechenden Index sofort updaten. Wenn Sie merken, dass Sie zusätzliche Indizes benötigen, dann können Sie diese später nachbestellen. Legen Sie daher nicht spekulativ für alle Eigenschaften einen Index an, sondern beschränken Sie sich auf diejenigen, die Sie momentan brauchen, und legen Sie weitere Indizes dann an, wenn Sie bemerken, dass gewisse Abfragen sehr langsam sind.

Relationale Datenbanken

Relationale Datenbanken (oder RDBMS) setzen als Hauptordnungssystem auf Tabellen. Alle Informationen werden in Tabellen verwaltet, und diese Tabellen sind genau so organisiert, wie man sich das intuitiv vorstellt: in Spalten (Columns) und Zeilen (Rows). Zwischen Einträgen in verschiedenen Tabellen können Bezüge (Relationen) hergestellt werden, was immer zeilenweise geschieht und zu zeilenweisen Ergebnissen führt.

Relationale Datenbanken sind dann das Mittel der Wahl, wenn Sie Daten in einem immer gleichen Format vor sich haben: Jeder Datensatz hat die gleichen Eigenschaften (also etwa Vor- und Nachname bei einer Person). Relationale Datenbanken sind gut darin, sehr große bis riesige Datenmengen zu verwalten, und können Datensätze nach bestimmten, benutzerdefinierten Kriterien sehr schnell filtern und ausgeben. Weniger gut eignen sie sich, um Daten mit flexiblen Eigenschaften zu speichern, etwa in einer Adressverwaltung, wo der Benutzer neben fixen Eigenschaften auch noch eigene Notizen zu jedem Eintrag hinzufügen will. Auch komplexe Datenstrukturen wie etwa eine HTML-Seite mit ihren verschachtelten Tags lassen sich in einer relationalen Datenbank nicht besonders gut ablegen.

Welche Eigenschaften Sie in einer Tabelle abbilden möchten, definieren Sie selbst, wenn Sie das sogenannte Datenbankschema aufsetzen. Das ist nichts anderes als eine Definition dafür, wie die Daten in der Datenbank abgelegt werden:

CREATE TABLE USER (

id INTEGER NOT NULL, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, department INTEGER,

PRIMARY KEY ('id')

);

Mit diesem Statement erstellen Sie eine Tabelle User mit vier Spalten , wobei jeder Datensatz eine lD, einen Vor- und Nachnamen sowie eine Abteilung haben soll.

Sie können diese Schemadefinitionen von Hand schreiben oder eines von vielen grafischen Frontends benutzen, mit dem sich Tabellendefinitionen, Indizes und teilweise auch Datenbankabfragen zusammenklicken lassen. Das bekannteste ist sicherlich Access von Microsoft, das aber an die Microsoft-Datenbanken gebunden ist. Für andere relationale Datenbanken gibt es ähnliche Tools.

Häufig legt man Tabellen so an, dass jeder Eintrag als erste Spalte (Eigenschaft) eine ID besitzt, und macht diese lD zum Primary Key (PK oder Primärschlüssel) der Tabelle. Primärschlüssel haben ein paar besondere Eigenschaften, unter anderem können sie nicht NULL sein und es kann keine zwei Zeilen in einer Tabelle geben, die den gleichen PK haben - der PK ist also eine Unique ID (siehe den Abschnitt »IDs, GUIDs, UUIDs« in Kapitel 26).

Relationale Datenbanken leben davon, dass Sie als Entwickler Wiederholungen in den Daten erkennen und in eigene Tabellen auslagern. Im Beispiel oben ist »Department«, also die Abteilung, in der ein Angestellter arbeitet, nur eine Zahl, obwohl eine Abteilung selbst einen Namen, ein oder mehrere Gebäude, Räume, Kostenstellen etc. hat. All diese Informationen will man aber nicht für jeden Angestellten immer und immer wieder in der User-Tabelle halten, sondern legt weitere Tabellen an: Department, Address und so weiter. Die Zahl in der User-Tabelle entspricht dann dem PK der Department-Tabelle und wird als Foreign Key bezeichnet. Dieses System, über Tabellen hinweg Beziehungen (Relationen) mithilfe von Foreign Key/Private Key-Beziehungen herzustellen, hat relationalen Datenbanken ihren Namen gegeben.1

Relationale Datenbanken werden in der Sprache SQL programmiert. SQL kann Daten in eine Datenbank füllen und sie auslesen, verändern sowie löschen. SQL bietet auch darü-

l

Wie Sie Wiederholungen durch Normalisierung Ihres Datenbankschemas entfernen, beschreiben wir in Kapitel 15.

ber hinaus noch eine ganze Menge Operationen wie Summieren, Aggregieren, Sortieren, aber die wichtigsten sind folgende:

•    INSERT. Damit fügt man Daten zeilenweise in eine Tabelle ein.

•    SELECT. Damit holt man seine Daten wieder aus der Datenbank.

•    UPDATE. Damit kann man die Inhalte einzelner Zellen in einer Datenbanktabelle verändern.

•    DE LETE. Löscht Daten zeilenweise.

Auch wenn die kleinste Einheit in einer relationalen Datenbank eine Zelle ist, also der Wert im Schnittpunkt einer Spalte und einer Zeile, sind die meisten Operationen doch zeilenweise angelegt. Daher schreibt man

SELECT firstname, lastname FROM USER;

und bekommt die Vor- und Nachnamen aus allen Zeilen der Datenbank zurück.

Es gibt auch spaltenweise Operationen wie SELECT DISTINCT lastname FROM USER;

Damit bekommen Sie eine Liste aller Nachnamen, wobei Dopplungen bereits entfernt wurden.

SQL ist eine deklarative Sprache (siehe den Abschnitt »Sprachfamilien« in Kapitel 26), was bedeutet, dass Sie keine Schleifen schreiben müssen (bzw. auch nur können). Sie schreiben SQL, indem Sie angeben, welche Operation (also SELECT oder INSERT) auf welche Tabelle angewendet werden soll, und können zusätzlich noch Filterkriterien angeben:

SELECT * FROM USER WHERE lastname = 'Meier'

ln einer imperativen Sprache müssten Sie eine Schleife schreiben, die über ein User-Array geht, jeden Eintrag untersucht und - falls er eine Eigenschaft »Nachname« mit dem Wert »Meier«« enthält - ihn in ein zweites Array steckt. Dieses zweite Array würden Sie dann zurückgeben:

function findUsersByLastName(usersln, lastName) { var resultUsers ; [];

for (var i = 0; i < usersln.length; i++) { if (usersln[i].lastName == lastName) { resultUsers.push(usersln[i]);

}

}

return resultUsers;

}

Relationale Datenbanken laufen traditionell auf einem Server, und zur Entwicklung benutzt man einen SQL-Client. Das ist ein Programm, das Sie auf Ihrem lokalen Rechner installieren und mit dem Sie sich mit der Datenbank verbinden. In diesem Programm können Sie SQL-Statements eingeben und die Ausgabe der Datenbank direkt betrachten. Wollen Sie eine relationale Datenbank direkt aus Ihrem Programm abtragen oder Daten in der Datenbank ablegen, dann benutzen Sie eine Bibliothek, die die Datenbank anspricht.

Neben diesem Client/Server-Modell, das noch aus der Zeit der großen Rechenzentren stammt, hat sich SQLite als lokale Datenbanklösung etabliert. Insbesondere im MobileBereich, wo es zu langsam wäre, jede SQL-Abfrage an einen Server zu stellen, spielt SQLite in der Programmierung von Apps eine wichtige Rolle. Der Vorteil: Wenn Sie SQL können, dann können Sie Ihre Daten wie auf einem Datenbankser'er lagern. Da das lokal auf dem Smartphone passiert, geht es aber viel schneller. SQLite ist auch toll, wenn man angstfrei mit der Speicherung von Daten aus einer Anwendung in eine Datenbank experimentieren will. Man braucht keinen Server, es ist schnell - und wenn man aus Versehen die Daten in der Datenbank durcheinandergebracht hat, kann man den Zustand von vorher leicht wiederherstellen, denn SQLite speichert alle Daten in einer lokalen Datei, die man einfach kopieren und archivieren kann.

NoSQL-Datenbanken

Relationale Datenbanken waren so lange eine gute Lösung, wie immer gleiche Daten mit einer festen Struktur verarbeitet wurden. Wenn eine Krankenkasse ihre Mitglieder und deren Arztrechnungen, Zahlungseingänge und Zuordnung zu Geschäftsstellen verwalten will, dann ist eine relationale Datenbank das Mittel der Wahl, denn für jedes Kassenmitglied werden bestimmte gleiche Merkmale wie Namen und Adressen zu einer Mitgliedsnummer erfasst. Alle Ärzte bekommen eine ID, alle Geschäftsstellen auch, und man kann dann Relationen zwischen Mitglied und Arzt aufstellen: Rechnung 49378 für Mitglied 72627, ausgestellt durch Arzt 2625 über 129,87 EUR. Statistiken über Kosten pro Mitglied, Ausgaben pro Arzt und dergleichen sind einfach zu entwickeln und laufen relativ schnell.

Diese Art von Anwendungen war und ist wichtig. Sie wird auch in der Zukunft existieren und vermutlich mit relationalen Datenbanken umgesetzt werden. Mit dem Aufkommen des Web zogen aber für die Alleinherrschaft der relationalen Datenbanken Wolken am Horizont auf. Content-Management-Systeme und Wikis verwalten keine strukturell immer gleichen Datensätze in großen Massen, sondern relativ wenige Datensätze, die aber in sich stark strukturiert sind. Die starre und schematische Art, wie Daten in relationalen Datensätzen gespeichert werden, passt eher schlecht zu Dokumenten, in denen eine oder mehrere Tabellen, Bilder oder keine, Links und diverse Überschriften vorkommen können. Wenn der Benutzer auch noch die Freiheit haben soll, sich eigene Elemente wie in den Text eingestreute Kästen mit einer bestimmten Formatierung auszudenken, wird die Entwicklungsarbeit ungeheuer mühsam.

Die neu aufkommenden Suchmaschinen und sozialen Netze hingegen hatten ziemlich entgegengesetzte Bedürfnisse, die vom relationalen Modell ebenfalls nicht gut abgedeckt waren: Sie müssen ungeheure Datenmengen verwalten und Suchanfragen in

Sekundenbruchteilen beantworten können. Für diese Anwendungen war die Abfrageseite relationaler Datenbanken nicht optimal, denn diese Datenbanken wurden entwickelt, um Anfragen der Art »gib mir die jeweiligen Umsätze aller Filialen über die letzten 12 Monate« zu beantworten. Zwar sind sie durchaus in der Lage, die Volltextsuchen zu unterstützen, wie sie Suchmaschinen benötigen, aber ihre Performance ist dafür nicht ideal. Die Verbindungen zwischen Nutzern von sozialen Netzwerken können zwar auch in relationalen Datenbanken gespeichert werden, und man kann Abfragen durchführen wie »gib mir alle Benutzer, die ähnliche Interessen wie der Benutzer Jander haben«, aber SQL ist für die Programmierung solcher Anfragen eher schlecht geeignet.

Daher wurden in den späten 1990er und frühen 2000er Jahren neue Datenbankkonzepte entwickelt, die nicht mehr auf das relationale Modell setzen und für die Abfrage kein SQL verwenden - und die man daher unter dem Begriff NoSQL zusammenfasst. Da diese Datenbanken zu einer Zeit entstanden sind, in der das Web schon alltäglich war, setzen sie auch für die Abfrage und Speicherung von Daten auf Webtechnologien. Man braucht also keinen Datenbank-Client zu installieren, wie man das bei RDBMS tun müsste, sondern kann für die Entwicklung direkt mit einem Webbrowser arbeiten. Will man diese Datenbanken dann aus einem Programm aufrufen, kann man eine Bibliothek wie cURL aus den eigenen Funktionen aufrufen oder direkt eine für die verwendete NoSQL-Daten-bank entwickelte Bibliothek.

Es gibt eine ganze Menge von NoSQL-Datenbanken, von denen für Einzelentwickler und kleine Gruppen besonders zwei Vertreter interessant sind:

Document Store-Datenbanken wie Couch DB oder MongoDB

Sie erlauben es, Daten mit einer ganz flexiblen Organisation abzuspeichern. Das ist ideal für Webseiten oder Content-Management-Systeme, denn man muss sich nicht überlegen, wie man eine Dokumentstruktur in der Datenbank abbildet. Die Benutzerin ist frei, dem Dokument ohne großen Programmieraufwand Absätze oder Links oder ursprünglich gar nicht vorgesehene neue Elemente hinzuzufügen.

Derartige Datenbanken haben keine Tabellen, keine Spalten und auch kein SQL. Statt-dessen werden JSON-Dokumente abgelegt, die Kind-Elemente enthalten können. Die Kind-Elemente können ihrerseits wieder andere Kind-Elemente enthalten. Als Entwickler schreiben Sie kleine JavaScript-Funktionen, um Abfragen durchzuführen.

Wollen Sie den Besuchern die Möglichkeit eröffnen, Blogposts zu kommentieren? Dann müssten Sie im relationalen Modell eine COMMENT-Tabelle anlegen, die die Besucherkommentare enthält; weiterhin eine Tabelle für VISITOR, in der Informationen wie Name und E-Mail-Adresse jedes Besuchers erfasst wird; und eine Zuordnungstabelle zwischen COM-MENT und VISITOR, um nachzuverfolgen, welcher Besucher welchen Kommentar geschrieben hat. Zwischen diesen drei Tabellen und der Tabelle für Blogposts müssten Sie dann ebenfalls noch eine Relation aufsetzen.

Im Document-Store-Modell ist das viel einfacher: Die Kommentare können einfach als zusätzliche Child-Objekte an jeden Blogpost angehängt werden und Sie haben dennoch die Möglichkeit, mit relativ wenig Aufwand alle Kommentare eines Spammers aus dem Verkehr zu ziehen. Diese Art der Ablage kommt unserem Denken viel näher: Kommentare zu einem Blogpost »gehören« diesem Posting und sind diesem untergeordnet. Das relationale Modell erfordert aber, sie vom Posting getrennt zu lagern und über Relationen später wieder zusammenzuführen.

Document-Store-Datenbanken sind immer dann eine gute Wahl, wenn Ihre Daten in der Struktur dynamisch sind oder Sie bei Beginn des Projekts noch nicht genau wissen, wie die Daten später strukturiert sein werden. Ändern sich nur die Inhalte, die Struktur aber eher selten, dann bieten sie keine großen Vorteile gegenüber relationalen Datenbanken. Auch Aggregations-Auswertungen (Summe der Verkäufe über alle Filialen, Durchschnittsgehälter der Mitarbeiter mit Maximal- und Minimalwerten) sind ihre Stärke nicht, dafür sind RDBMS erfunden worden.

Graphdatenbanken wie neo4j

Geht es hauptsächlich um die Vernetzung zwischen Datensätzen, dann könnten Graphdatenbanken eine gute Wahl sein, egal, ob es sich um chemische Reaktionswege, Geldflüsse oder soziale Netzwerke handelt. Anwendungen können beispielsweise ein Empfehlungssystem wie bei Amazon sein: Wenn das System Kunden und Artikel als Knoten modelliert und Käufe als Verbindungen zwischen einem Kundenknoten und einem Artikelknoten, dann kann es ziemlich einfach für einen Kunden A anhand seiner Käufe andere Kunden mit ähnlichen Kaufgewohnheiten finden. Geht es deren Käufe durch, dann kann es sie mit den Käufen von Kunde A vergleichen und diesem Kunden diejenigen Artikel vorschlagen, die er selbst bisher nicht gekauft hat, die aber von ähnlich veranlagten Kunden gerne gekauft werden.

Das Datenbankmodell von Graphdatenbanken ist ausgesprochen spartanisch: Es gibt nur Knoten und Verbindungen. Knoten können Eigenschaften wie eine ID, einen Namen oder vom Entwickler definierte, frei gewählte Eigenschaften besitzen. Die Verbindungen werden üblicherweise mit Verben wie »knows«, >>likes« (bei sozialen Netzwerken) oder »inhibits«, >>catalyzes<< (in der Wissenschaft) belegt.

Facebook hat mit der >>Graph search« eine Anwendung implementiert, die mit einer Graphdatenbank recht einfach umzusetzen ist. Man kann damit sein soziales Umfeld durchsuchen und Anfragen stellen wie >>such mir die Freunde meiner Freunde, die auch häufig ins >Gehäkelte Einhorn gehen und gern Johnny Cash hören«.

Auch Graphdatenbanken werden nicht mit SQL durchsucht. Teilweise besitzen sie eine SQL-ähnliche Abfragesprache, teilweise müssen Sie die Abfragen selbst programmieren.

Egal, für welche Art der Datenaufbewahrung Sie sich entscheiden: Treffen Sie diese Entscheidung bewusst und nicht aufgrund einer diffusen Abneigung gegen eine bestimmte

Technologie (»XML ist sooo 20. Jahrhundert!«) oder der Sorge, alternative Technologien nicht zu beherrschen. Es ist zwar Aufwand, sich in eine Datenbanktechnologie einzuarbeiten, aber auf längere Sicht kann es viel mehr Arbeit sein, sich jahrelang mit einer im Grunde ungeeigneten Technologie herumzuschlagen. Jedes weitere Stück Code, das Sie schreiben, um Ihr System in Gang zu halten, macht es schwieriger, auf eine bessere Mög-1ichkeit umzusteigen.