Eine Datenbank ist der Teil einer Anwendung, der Daten so speichert, dass sie auch nach einem Neustart der Anwendung, einem Serverabsturz oder einem Stromausfall erhalten bleiben. Die Anwendung kann diese Daten später in spezifischen Formaten abrufen, etwa als einzelnen Datensatz (identifiziert über eine ID) oder als nach Benutzer gefilterte Liste.
Um den Begriff „Daten“ zu konkretisieren, betrachten wir eine einfache Aufgabenliste. Jede Aufgabe ist ein Datensatz mit Feldern wie task_id, user_id, title, completed und created_at; die Anwendung benötigt dazu zwei grundlegende Funktionen: eine zum Erstellen einer Aufgabe und eine zum Auflisten der Aufgaben eines Benutzers.
In einem Szenario mit einem einzelnen Server sendet der Client HTTP-Anfragen an einen Anwendungsserver, der wiederum Datensätze in einer Datenbank liest und schreibt. Die Datenbank gewährleistet Korrektheit, indem sie Regeln durchsetzt – etwa die Vorgabe, dass ein Aufgabendatensatz pro Anfrage genau einmal geschrieben wird. Gleichzeitig verursacht sie Latenz, da Lese- und Schreibvorgänge auf dem Datenträger und im Arbeitsspeicher Zeit in Anspruch nehmen. Verfolgen wir die beiden Anfragepfade anhand eines Blockdiagramms.
Bei einer Anfrage zum Erstellen einer Aufgabe validiert der Anwendungsserver die Eingabe, weist die Datenbank an, einen neuen Datensatz für die Aufgabe einzufügen, und sendet anschließend die neue task_id an den Client zurück. Der Schreibvorgang gilt für den Client erst dann als dauerhaft abgeschlossen, wenn die Datenbank ihn bestätigt hat; daher ist die Datenbank ein entscheidender Faktor für die Korrektheit des Systems.
Bei einer Anfrage zum Auflisten von Aufgaben fragt der Anwendungsserver die Datenbank nach allen Aufgaben ab, bei denen die user_id übereinstimmt (oft sortiert nach created_at), und formatiert anschließend die Antwort. Wenn die Abfrage mehr Datensätze durchsucht als erforderlich, steigt der Arbeitsaufwand für die Datenbank und die Wartezeit für den Client verlängert sich; die Leistung hängt also maßgeblich davon ab, wie effizient die Datenbank die passenden Datensätze findet.
Wenn immer mehr Benutzer Aufgaben hinzufügen, zeigt sich das erste Problem meist darin, dass die Auflistung der Aufgaben (list-tasks) langsam wird, weil die Datenbank für eine einzelne Abfrage zu große Datenmengen lesen muss. Als Nächstes können ein sehr aktiver Benutzer oder eine gemeinsam genutzte Liste zu Wartezeiten durch Sperren (Locks) führen: Wenn viele Schreibvorgänge versuchen, denselben Datensatz oder dieselbe Gruppe von Datensätzen zu aktualisieren, reihen sich die Anfragen nacheinander auf, anstatt parallel verarbeitet zu werden. Fällt schließlich der einzelne Datenbankprozess oder der Server aus, kann die gesamte Anwendung keine Anfragen mehr bearbeiten, da sie von dieser einen Komponente abhängt. Das folgende Diagramm veranschaulicht diese drei kritischen Punkte auf einer gemeinsamen Zeitachse.