Was ist NoSQL? Datenmodelle, Unterschiede zu SQL und Einsatzbereiche

NoSQL-Datenbanken sind eine Familie von Datenbanken, die Modelle wie Dokumente, Schlüssel-Wert-Paare, Wide-Column-Strukturen und Graphen verwenden, anstatt sich auf das relationale Tabellenmodell zu stützen. Wählen Sie eines für die Struktur Ihrer Daten und die Operationen, die Ihre Anwendung benötigt; das NoSQL-Label allein garantiert weder schnellere Abfragen noch einfacheres Design.

SQL (Structured Query Language) ist eine Sprache zur Abfrage und Manipulation von Daten, während NoSQL eine Kategorie ist, die mehrere Modelle abdeckt. „Not Only SQL“ ist eine Möglichkeit, den Namen zu erklären; es bedeutet nicht, dass jedes Produkt SQL verbietet. Der AWS NoSQL Überblick beschreibt die verschiedenen Modelle und Zwecke.

Die vier Haupt-NoSQL-Datenmodelle

Diese Kategorien beschreiben, wie Daten dargestellt werden. Ein Produkt kann mehrere Modelle unterstützen, und Produkte in derselben Kategorie können sich in Abfragefähigkeiten und Operationen unterscheiden.

Modell Grundlegende Darstellung Zu berücksichtigende Arbeitslast Beispiele
Schlüssel-Wert Ein eindeutiger Schlüssel und sein zugehöriger Wert Cache- oder Sitzungssuchen nach bekannten Schlüsseln Redis, Amazon DynamoDB
Dokument Dokumente mit Feldern, Arrays und verschachtelten Objekten Produktkataloge mit unterschiedlichen Attributen, Benutzerprofile MongoDB
Wide-Column Zeilen oder Partitionen, organisiert nach Schlüsseln und Spalten Ereignisaufzeichnungen, abgefragt nach Gerät oder Zeitbereich Apache Cassandra, Bigtable
Graph Knoten für Entitäten und Kanten für Beziehungen Empfehlungen, Abhängigkeiten und Pfadnavigation Neo4j

Schlüssel-Wert-Datenbanken

Ein Schlüssel-Wert-Modell sucht einen Wert mithilfe eines Schlüssels wie session:abc123. Berücksichtigen Sie dies, wenn der Zugriff vorhersehbar ist, z.B. beim Abrufen einer Sitzung anhand ihrer ID. Das Durchsuchen beliebiger Bedingungen innerhalb von Werten erfordert eine Überprüfung der Indexierungs- und Abfragefunktionen des jeweiligen Produkts.

Werte müssen nicht nur einfache Zeichenketten sein. Redis unterstützt neben Zeichenketten auch Hashes, Listen, Sets und sortierte Sets, wie in seiner Datentypreferenz dokumentiert. Für einen Cache sollten Sie außerdem entscheiden, wo die autoritativen Daten gespeichert werden, wann Einträge ablaufen und was passiert, wenn ein zwischengespeicherter Eintrag fehlt.

Dokumentdatenbanken

Ein Dokument gruppiert die Felder, Arrays und verschachtelten Objekte eines Elements. JSON (JavaScript Object Notation) ist ein Textformat zur Darstellung solcher Strukturen; MongoDB speichert Dokumente unter Verwendung von BSON (Binary JSON). Ziehen Sie Dokumente für Elemente mit unterschiedlichen Attributen in Betracht oder für Daten, die häufig zusammen auf einem Bildschirm gelesen werden.

Wählen Sie zwischen dem Einbetten verwandter Informationen in ein Dokument und dem Verweisen auf die Kennung eines anderen Dokuments, abhängig von Zugriffsfrequenz, Größe und Aktualisierungen. Das Kopieren einer Adresse in jede Bestellung kann das Lesen vereinfachen, aber Sie müssen entscheiden, was die Kopie bedeutet und wie sie gepflegt wird. Der MongoDB-Modellierungsleitfaden empfiehlt, das Design an den Zugriffsmustern auszurichten.

Wide-Column-Datenbanken

Wide-Column-Modelle organisieren Daten um Zeilen- oder Partitionsschlüssel und Spalten herum. Bigtable verwendet eine nach Zeilenschlüssel sortierte Map und gruppiert verwandte Spalten in Spaltenfamilien. Seine Speichermodell-Dokumentation erklärt Zeilen, Spalten und Familien.

Ein Wide-Column-Store sollte nicht als dasselbe wie ein analytischer Spalten-Store behandelt werden, der die Werte einer Spalte zusammen gruppiert. Cassandra erfordert eine abfrageorientierte Tabellen- und Partitionsgestaltung und unterstützt keine relationalen Joins. Seine Einführung in die Datenmodellierung erklärt, warum man zuerst Fragen identifizieren sollte wie „lese die Datensätze dieses Geräts für diesen Zeitraum“. Prüfen Sie, ob der Kandidat Ihre erforderlichen Bereichsabfragen und Aggregationen unterstützt.

Graphdatenbanken

Ein Graph stellt Entitäten, wie Personen, Produkte oder Server, als Knoten und deren Verbindungen als Kanten dar. Ziehen Sie dies für Fragen in Betracht, die Beziehungen verfolgen, wie die Identifizierung von Diensten, die von einem Serverausfall betroffen sind.

Graphen können auch Attribute speichern. Das Property-Graph-Modell von Neo4j erlaubt Eigenschaften sowohl auf Knoten als auch auf Beziehungen, wie in seiner Graph-Konzeptleitfaden erklärt. Ein Graph-Modell macht nicht jede Abfrage schnell; definieren Sie Traversierungstiefe, Beziehungstypen und Pfadbedingungen.

Wie unterscheidet sich NoSQL von einer relationalen Datenbank?

Ein relationales Datenbankmanagementsystem (RDBMS) organisiert Daten mithilfe von Tabellen, Schlüsseln und Einschränkungen. Es bietet eine nützliche Grundlage zum Verbinden verwandter Datensätze und Anwenden gemeinsamer Regeln. Ein NoSQL-Produkt bietet Operationen, die seinem Modell entsprechen, daher vergleichen Sie, wie jeder Kandidat die Fragen Ihrer Anwendung beantwortet, anstatt ein bestehendes Schema unverändert zu übernehmen.

Entscheidungsbereich Was in einem relationalen Modell zu prüfen ist Was in einem NoSQL-Modell zu prüfen ist
Struktur Spalten, Typen, Schlüssel und Einschränkungen Dokumente, Schlüssel, Partitionen oder Graphbeziehungen
Abfragen und Beziehungen Joins, Aggregationen und verschiedene Filter Einbettung, Referenzen, Schlüsselabfragen oder Graphtraversierung
Änderung und Validierung Schemaveränderungen und Auswirkungen auf vorhandene Daten Erforderliche Felder, Typen und Versionierung, selbst bei flexiblen Strukturen
Transaktionen und Konsistenz Isolation und Aktualisierungen über Tabellen hinweg Unterstützter Umfang, Bereitstellungsanforderungen und Lese-/Schreib-Einstellungen
Skalierung und Betrieb Indizes, Replikation, Verteilung und betriebliche Komplexität Verteilungsschlüssel, Replikate, Rebalancing, Kosten und Wiederherstellung

Das Speichern von JSON erfordert nicht automatisch NoSQL. PostgreSQL bietet beispielsweise JSON-Typen und Indexierung für jsonb; siehe dessen JSON-Typ-Dokumentation. Die Beibehaltung relationaler Regeln und Transaktionen bei der Verwendung flexibler Attribute für einen Teil der Daten ist ebenfalls ein geeignetes Design.

Ein flexibles Schema muss noch entworfen werden

Ein Schema definiert Struktur und Regeln, wie Feldnamen, Typen und erforderliche Werte. Auch wenn Dokumente unterschiedliche Felder haben können, benötigt eine Anwendung vorhersehbare Daten. Dieser fiktive JSON-Katalog veranschaulicht zwei Produkte mit unterschiedlichen Attributen:

[
  {
    "product_id": "book-101",
    "name": "Database Basics",
    "price_krw": 24000,
    "attributes": {
      "author": "Mina Kim",
      "pages": 320
    }
  },
  {
    "product_id": "headphones-201",
    "name": "Wireless Headphones",
    "price_krw": 79000,
    "attributes": {
      "wireless": true,
      "battery_hours": 30
    }
  }
]

Beide Produkte teilen product_id, name und price_krw, aber ihre verschachtelten attributes sind unterschiedlich. Eine Dokumentstruktur drückt diese Variation auf natürliche Weise aus. Die Mischung von Zahlen und Zeichenketten im selben Preisfeld kann jedoch die Sortierung und Berechnung erschweren, daher sollten erlaubte Typen und die Behandlung fehlender Werte definiert werden.

MongoDB unterstützt Validierungsregeln für Typen und Wertebereiche; die Dokumentation zur Schema-Validierung erklärt, wie Regeln dort angewendet werden, wo sie benötigt werden. CQL (Cassandra Query Language) von Cassandra definiert hingegen Spalten und Typen beim Erstellen einer Tabelle, wie in der Referenz zur Tabellendefinition gezeigt. „Jede NoSQL-Datenbank ist schemalos“ ist daher ungenau.

JSON beschreibt eine Struktur; es handelt sich nicht um von Natur aus unstrukturierte Daten. Entscheiden Sie separat, ob Bilder und Videos in einer Datenbank oder in einem Objektspeicher mit ihren Speicherorten und Metadaten in einer Datenbank abgelegt werden sollen. Dateigröße, Anforderungen an die Auslieferung und Verwaltungsbedürfnisse beeinflussen diese Entscheidung.

Überprüfen Sie Transaktions- und Konsistenzgarantien je nach Produkt

Transaktionsunterstützung und -umfang

Eine Transaktion behandelt Änderungen als eine Arbeitseinheit. ACID bedeutet Atomarität, Konsistenz, Isolation und Dauerhaftigkeit. Für Änderungen, die gemeinsam erfolgreich sein oder fehlschlagen müssen, wie das Erstellen einer Bestellung und das Verringern des Lagerbestands, sollten zuerst die erforderlichen Garantien festgelegt werden.

NoSQL bedeutet nicht das Fehlen von Transaktionen. MongoDB unterstützt Multi-Dokument-Transaktionen in Replikatsätzen und geshardeten Clustern, wobei die Garantien durch die Bereitstellung und Lese-/Schreibeinstellungen beeinflusst werden; siehe dazu die Transaktionsdokumentation. DynamoDB bietet ebenfalls transaktionale APIs (Application Programming Interfaces), hat jedoch Einschränkungen, einschließlich der unterstützten Ziele und des Regionsbereichs. In der Transaktionsreferenz werden diese Grenzen erläutert.

Was kann ein Lesevorgang unmittelbar nach einem Schreibvorgang zurückgeben?

Das Replikationsverhalten ist ebenfalls wichtig. Bei letztendlich konsistenten Lesevorgängen kann ein kürzlich abgeschlossener Schreibvorgang möglicherweise noch nicht im Leseergebnis erscheinen. Definieren Sie die Anforderungen pro Benutzeraktion: Kann eine Bestellung unmittelbar nach dem Speichern durch den Benutzer vorübergehend fehlen?

DynamoDB-Tabellen und lokale Sekundärindizes können stark konsistente Lesevorgänge verwenden, während Lesevorgänge aus globalen Sekundärindizes und Streams letztendlich konsistent sind. Siehe die Dokumentation zur Lesekonsistenz für Unterschiede nach Abfrageziel. ACID-Konsistenz innerhalb einer Transaktion und Konsistenz von Lesevorgängen über Replikate hinweg sind unterschiedliche Aspekte.

Horizontale Skalierung garantiert keine Leistung

Horizontale Skalierung fügt Server hinzu, anstatt einen Server durch eine größere Maschine zu ersetzen. Sharding verteilt Daten über Server; Replikation hält Kopien bereit. Mehrere Server allein garantieren weder ausgeglichene Daten noch schnellere Abfragen. Die MongoDB Sharding-Übersicht beschreibt verteilte Konfigurationen separat.

Ein schlecht verteilter Schlüssel kann Anfragen auf eine heiße Partition konzentrieren. Zum Beispiel kann das Zusammenfassen jedes Ereignisses unter einem festen Schlüssel der Lastverteilung entgegenwirken. Betrachten Sie Zugriffsmuster und Schlüsseldistribution gemeinsam, wie in DynamoDBs Anleitung zum Partitionierungs-Schlüssel erklärt.

Die Leistung hängt von der Datengröße, den Indizes, dem Abfragebereich, dem Lese-/Schreibverhältnis, den Konsistenz-Einstellungen und der Arbeitslast ab. Vergleichen Sie die Latenz bei langsamen Anfragen, Ausfälle und Wiederherstellungsverhalten zusammen mit der durchschnittlichen Reaktionszeit. Berücksichtigen Sie in der Kostenbewertung auch Replikate, Backups, Netzwerk und operative Arbeiten; die NoSQL-Kategorie allein begründet keine niedrigeren Kosten.

Wann sollten Sie NoSQL in Betracht ziehen?

  • Bekannte Schlüssel im Cache oder Sitzungszugriff: Ziehen Sie einen Key-Value-Store in Betracht, während Sie Ablauf, Persistenz und Synchronisierung mit den autoritativen Daten festlegen.
  • Katalogartikel mit variierenden Attributen: Ziehen Sie Dokumente in Betracht, während Sie die Validierung gemeinsamer Felder und Suchindizes entwerfen.
  • Ereignisse, die anhand eines bekannten Schlüssels und Zeitraums abgefragt werden: Ziehen Sie eine Wide-Column-Speicherung in Betracht, während Sie die Partitionsgröße und Bereichsabfragen prüfen.
  • Mehrstufige Beziehungstraversierung: Betrachten Sie einen Graphen, während Sie Verbindungstypen und Traversierungstiefe definieren.

Wenn unterschiedliche Berichte mehrere Tabellen zusammenführen oder Integritätsregeln über Datensätze hinweg eine zentrale Durchsetzung benötigen, verdient eine relationale Datenbank eine frühe Vergleichsbetrachtung. Treffen Sie keine Entscheidung nur aufgrund eines Branchenlabels oder Datenvolumens: Untersuchen Sie, wie die wichtigsten Lese- und Schreibvorgänge in jedem Kandidaten funktionieren würden.

Sie können verschiedenen Stores unterschiedliche Rollen zuweisen, z. B. eine relationale Datenbank als autoritative Quelle und einen Key-Value-Store als Cache verwenden. Zusätzliche Stores machen auch das Aktualisieren von Kopien, die Weitergabe von Löschungen und Wiederherstellung komplexer, daher fügen Sie sie nur hinzu, wenn ein nachgewiesener Bedarf besteht.

Eine praktische Evaluierungsabfolge

  1. Schreiben Sie die wichtigen Abfragen auf. Geben Sie Filter und Reihenfolge für Aufgaben wie Produktsuche nach ID, aktuelle Benutzerbestellungen oder die täglichen Aufzeichnungen eines Geräts an.
  2. Definieren Sie Korrektheitsanforderungen. Erfassen Sie Änderungen, die gemeinsam erfolgreich sein müssen, Umgang mit doppelten Anfragen, sofortige Lesezugriffe und akzeptable veraltete Werte.
  3. Entwerfen Sie tatsächliche Kandidatenmodelle. Untersuchen Sie die Dokumentgröße, Einbettung oder Referenzen, Indizes, Partitionierungsschlüssel und Abfragepfade, während die Daten wachsen.
  4. Vergleichen Sie kleine Implementierungen. Verwenden Sie dieselben Daten und Operationen, um normale Last, konzentrierte Last und Ausfälle zu reproduzieren; protokollieren Sie Produktversionen und Einstellungen.
  5. Planen Sie Betrieb und Migration. Überprüfen Sie Berechtigungen, Sicherung und Wiederherstellung, Überwachung, Migration, erwartete Kosten und einen Rückweg zum bestehenden Store, falls nötig.

Beginnen Sie mit den Abfragen und den Korrektheitsanforderungen, dann wählen Sie ein Modell und ein Produkt, das diese erfüllt. Wenn die bereits verwendete Datenbank diese Anforderungen erfüllt, stellen Sie den Grund für das Hinzufügen eines weiteren Speichertyps fest, bevor Sie ihn einführen.