Konsistenz (Datenspeicherung)
# Konsistenz (Datenspeicherung)

Als Konsistenz wird in Datenbanken die Korrektheit der dort gespeicherten Daten bezeichnet. Inkonsistente Datenbanken können zu schweren Fehlern führen, falls die darüberliegende Anwendungsschicht nicht damit rechnet. Man kann dabei zwei grundlegende Perspektiven auf Konsistenz von Daten unterscheiden, einerseits aus der Welt der „klassischen“ relationalen Datenbanken und andererseits aus der Welt der verteilten Systeme.

## Verteilte Systeme

Verteilte Speichersysteme haben im Zuge des Cloud-Computing großen Auftrieb und Bekanntheit erlangt. In verteilten Speichersystemen werden Daten üblicherweise mehrfach über verschiedene Server verteilt repliziert, um einerseits die Verfügbarkeit der Daten zu erhöhen und andererseits die Zugriffszeiten zu verringern. Ersteres ist klar ersichtlich, da die Wahrscheinlichkeit, dass mehrere Server gleichzeitig ausfallen deutlich geringer ist, als dass lediglich einer ausfällt. Letzteres erklärt sich dadurch, dass Zugriffe wahlweise an geografisch nähere Replikas geschickt werden können oder ein völlig überlasteter Server entlastet wird, indem ein Teil der Zugriffe von einem anderen Server übernommen wird. In diesem Kontext bedeutet Konsistenz, dass alle Replikas eines Datums identisch sind. Insbesondere bedeutete dies auch, dass ein verteiltes Speichersystem für einen Datensatz A konsistent und gleichzeitig für einen Datensatz B inkonsistent sein kann. Man spricht auch von strikter Konsistenz, wenn alle Replikas immer identisch sind.
Da es in verteilten Systemen nicht immer sinnvoll ist, alle Replikas konsistent zu halten, gibt es hier auch sogenannte schwache Konsistenz (englisch weak consistency), d. h., es werden keinerlei Konsistenzgarantien abgegeben, und die sogenannte eventual consistency, die besagt, dass ein Datensatz irgendwann konsistent sein wird, sofern nur eine hinreichend lange Zeit ohne Schreibvorgänge und Fehler vorausgesetzt werden kann.
Im Spektrum zwischen eventual und strikter Konsistenz gibt es noch einige Zwischenstufen, dabei unterscheidet man zwischen sogenannter client-centric consistency und data-centric consistency. Ersteres beschreibt Konsistenzgarantien aus der Sicht des Clients, letzteres interne Konsistenzgarantien.

### Client-Centric Consistency
#### Monotonic Read Consistency

Wenn ein verteiltes Speichersystem einmal auf eine Leseanfrage eines Clients für einen bestimmten Schlüssel mit Version N geantwortet hat, werden alle späteren Lesezugriffe dieses Clients nur noch Versionen, die mindestens so neu sind wie N, zurückliefern.

#### Monotonic Write Consistency

Wenn ein bestimmter Client für einen bestimmten Schlüssel erst Wert 1 und dann Wert 2 schreibt, dann ist garantiert, dass das System intern die Werte ebenfalls in dieser Reihenfolge schreibt. Das bedeutet insbesondere, dass (ohne weitere Schreibzugriffe) in einer Replika niemals Wert 1 Wert 2 überschreiben wird.

#### Read Your Writes Consistency

Hier garantiert das Speichersystem, dass ein Prozess, der ein Datum mit der Versionsnummer N geschrieben hat, garantiert keine Versionen lesen wird, die älter sind als N. Eine triviale Implementierung hiervon wären lokal im Client vorgehaltene Replikas, die nicht synchronisiert werden. Allerdings würde dies nur schwache Konsistenz und keine eventual consistency garantieren. In der Praxis wird dies durch sogenannte Session Consistency umgesetzt, bei der diese Garantie nur für die Dauer einer Session gilt. Beispielsweise ist es dann möglich, alle Anfragen (egal ob Lese- oder Schreibzugriff) eines bestimmten Prozesses zur selben Replika zu routen. Ist diese Replika nicht verfügbar, wird die Session beendet.

#### Write Follows Reads Consistency

Wenn ein Prozess ein Datum X in einer Version N gelesen hat und anschließend derselbe Prozess dieses Datum überschreibt, dann garantiert Write Follows Reads Consistency, dass der Schreibvorgang nur auf einer Replika von X stattfindet, die mindestens in Version N vorliegen.

### Data-centric Consistency
#### Causal Consistency

Causal Consistency bedeutet, dass alle Operationen, die in einer kausalen Beziehung stehen, in der gleichen Reihenfolge auf allen Replikas serialisiert werden müssen. Eine Operation O ist genau dann kausal von einer Operation P abhängig, wenn ein oder mehr der folgenden Bedingungen gelten:
* O und P wurden beide vom gleichen Prozess ausgelöst und P lag chronologisch vor O.
* O ist ein Read, P ist ein Write und O hat das Ergebnis von P gelesen.
* O ist kausal abhängig von einer Operation X, die wiederum kausal abhängig von P ist (Transitivität).

#### Sequential Consistency

Sequential Consistency ist strikter als Causal Consistency, indem das Modell erfordert, dass alle Operationen in der gleichen Reihenfolge auf allen Replika serialisiert werden und die Operationen jedes Clientprozesses in ihrer korrekten finalen Reihenfolge ausgeführt werden.

#### Linearizability

Linearizability ist strikter als Sequential Consistency, indem das Modell darüber hinaus erfordert, dass die einheitliche Ordnung der Operationen der tatsächlichen chronologischen Reihenfolge entspricht und alle Requests so erscheinen, als würden sie anstelle während eines Zeitintervalls an einem Zeitpunkt passieren.

## Konsistenz in klassischen relationalen Datenbanken

In relationalen Datenbanken versteht man unter Konsistenz die Integrität von Daten. Diese wird durch das Aufstellen von sogenannten Integritätsbedingungen definiert. Man unterscheidet verschiedene Arten der Integritätsbestimmungen:

### Bereichsintegrität

    Der Wert jedes Attributes muss in einem bestimmten Wertebereich liegen.

### Entitätsintegrität

    Der Primärschlüssel jedes Objekts muss eindeutig sein. Der Feldinhalt darf auf keinen Fall leer (Sql: Not Null) sein.

### Referentielle Integrität

    Der Inhalt eines Fremdschlüsselfeldes muss entweder leer (Null) sein, oder ein Objekt mit einem solchen Schlüssel muss existieren.

### Logische Konsistenz

    Der Benutzer kann auch zusätzliche Integritätsbestimmungen definieren (z. B. bei einer Stammbaumdatenbank: Die Kinder müssen nach den Eltern geboren worden sein). Solche Bedingungen können in der Regel vom Datenbanksystem nicht kontrolliert werden und müssen deshalb vom Benutzer selbst erfüllt werden.
Eine Datenbank ist nur konsistent, wenn sie alle Integritätsbestimmungen erfüllt. Ein Zustand, in dem mindestens eine Integritätsbedingung verletzt wird, wird als nicht konsistent bezeichnet.
Konsistenz in klassischen relationalen Datenbanken ist eine Obermenge der Konsistenzdefinition aus der Welt der verteilten Systeme, d. h. solange nicht alle Replikas identisch sind, können auch die Integritätsbedingungen nicht alle erfüllt sein.

### Konsistente Transformationen

Konsistenz ist eine der vier von Datenbank-Transaktionen geforderten ACID-Eigenschaften. Jede Transaktion muss eine Datenbank von einem konsistenten in einen anderen konsistenten Zustand überführen. Während der Verarbeitung der Anfrage kann die Konsistenz der Datenbank jedoch kurzfristig verletzt werden.
Nach jeder durch eine Transaktion gegebenen Reihe von Veränderungen der Daten (Einfügen, Löschen oder Ändern) wird die Datenbank auf die Integritätsbedingungen geprüft. Falls diese nicht erfüllt sein sollten, muss die gesamte Transaktion so zurück abgewickelt werden, dass der vorige (konsistente) Zustand wiederhergestellt wird („Rollback“).
Besondere Vorsicht erfordern parallel ablaufende Transaktionen.