Cassandra Datenmodell mit einfachem Datenbankbeispiel

⚡ Intelligente Zusammenfassung

Cassandra Die Regeln des Datenmodells kehren die Gewohnheiten des relationalen Designs um: Tabellen werden für Abfragen statt für Entitäten erstellt. Diese Seite behandelt die Kernregeln, die Auswahl von Partitionsschlüsseln und Beispielschemata für 1:1-, 1:n- und n:m-Beziehungen.

  • ✍️ Schreiben ist billig: Cassandra ist auf Schreibdurchsatz optimiert, daher ist das Duplizieren von Daten über Tabellen hinweg die gängige Methode, um Lesevorgänge zu beschleunigen.
  • 📋 Zuerst die Frage stellen: Listen Sie die Abfragen auf, die die Anwendung beantworten muss, und erstellen Sie dann für jede Abfrage eine eigene Tabelle anstatt für jede Entität eine eigene Tabelle.
  • 🔑 Partitionsschlüssel: Das erste Element des Primärschlüssels bestimmt, welcher Knoten die Zeile speichert und somit, wie gleichmäßig die Daten verteilt werden.
  • 🧩 ClusterSpalten: Die übrigen Primärschlüsselelemente sortieren Zeilen innerhalb einer Partition und ermöglichen Bereichsabfragen.
  • 📏 Partitionsgröße: Zu wenige Partitionen erzeugen Hotspots und übergroße Zeilen; zu viele zwingen einen Lesevorgang dazu, viele Knoten zu besuchen.
  • 🔗 Beziehungen: Für eine Eins-zu-Eins-Beziehung wird eine einzelne Tabelle benötigt, für eine Eins-zu-Viele-Beziehung ein zusammengesetzter Schlüssel und für eine Viele-zu-Viele-Beziehung wird pro Abfragerichtung eine Tabelle benötigt.

Cassandra Beispiel für ein Datenmodell

Obwohl Cassandra Die Abfragesprache ähnelt SQL Sprache, ihre Datenmodellierungsmethoden sind völlig unterschiedlich.

In Cassandra, ein schlechtes Datenmodell kann die Leistung beeinträchtigen, insbesondere wenn Benutzer versuchen, die RDBMS-Konzepte auf Cassandra. Beachten Sie am besten einige der unten aufgeführten Regeln.

Cassandra Datenmodellregeln

In Cassandra, schreibt sind nicht teuer. Cassandra unterstützt keine Verknüpfungen, Gruppierungen nach, OR-Klauseln, Aggregationen usw. Daher müssen Sie Ihre Daten so speichern, dass sie vollständig abrufbar sind. Daher müssen diese Regeln bei der Modellierung von Daten beachtet werden Cassandra.

Maximieren Sie die Anzahl der Schreibvorgänge

In Cassandra, schreibt sind sehr günstig. Cassandra ist auf hohe Schreibleistung optimiert. Maximieren Sie daher Ihre Schreibvorgänge, um eine bessere Leseleistung und Datenverfügbarkeit zu erzielen. Es besteht ein Zielkonflikt zwischen Datenschreib- und Datenlesevorgängen. Optimieren Sie daher Ihre Leseleistung, indem Sie die Anzahl der Schreibvorgänge maximieren.

Maximieren Sie die Datenduplizierung

Datendenormalisierung und Datenduplizierung sind de facto der Fall Cassandra. Festplattenspeicher ist nicht teurer als Arbeitsspeicher, CPU-Verarbeitung und IO-Operationen. Cassandra Da es sich um eine verteilte Datenbank handelt, bietet die Datenduplizierung eine sofortige Datenverfügbarkeit und keinen Single Point of Failure.

Cassandra Datenmodellierungsziele

Sie sollten folgende Ziele haben, wenn Sie Daten modellieren in Cassandra:

Verteilen Sie die Daten gleichmäßig Cluster

Sie möchten auf jedem Knoten von die gleiche Datenmenge Cassandra ClusterDie Daten werden anhand von Partitionsschlüsseln, die den ersten Teil des Primärschlüssels bilden, auf verschiedene Knoten verteilt. Wählen Sie daher möglichst eine Spalte mit hoher Kardinalität als Partitionsschlüssel, um die Daten gleichmäßig im Cluster zu verteilen.

Minimieren Sie die Anzahl der beim Abfragen von Daten gelesenen Partitionen

Partitionen sind eine Gruppe von Datensätzen mit demselben Partitionsschlüssel. Wenn die Leseabfrage ausgegeben wird, werden Daten von verschiedenen Knoten aus verschiedenen Partitionen gesammelt.

Wenn es viele Partitionen gibt, müssen alle diese Partitionen besucht werden, um die Abfragedaten zu sammeln.

Das bedeutet nicht, dass keine Partitionen erstellt werden sollten. Bei sehr großen Datenmengen ist es nicht möglich, diese auf einer einzigen Partition zu speichern. Die Leistung würde dadurch stark beeinträchtigt.

Versuchen Sie daher, eine ausgewogene Anzahl an Partitionen zu wählen.

Guter Primärschlüssel Cassandra

Beide oben genannten Ziele hängen von einer einzigen Entscheidung ab. Die beiden folgenden Schemata zeigen daher dieselbe Tabelle einmal mit einem ungeeigneten Schlüssel und einmal mit einem geeigneten Schlüssel.

Nehmen wir ein Beispiel und finden wir heraus, welcher Primärschlüssel gut ist.

Hier ist die Tabelle MusicPlaylist.

CREATE TABLE MusicPlaylist (
    SongId int,
    SongName text,
    Year int,
    Singer text,
    PRIMARY KEY (SongId, SongName)
);

Im obigen Beispiel, Tabelle MusicPlaylist,

  • SongId ist der Partitionsschlüssel, und
  • SongName ist die Clustering-Spalte
  • Die Daten werden anhand des Songnamens gruppiert. Pro Song-ID wird nur eine Partition erstellt, und da jeder Song eine eindeutige Kennung hat, enthält jede Partition eine einzelne Zeile.

Der Datenabruf ist bei diesem Datenmodell aufgrund des fehlerhaften Primärschlüssels langsam.

Hier ist eine weitere Tabelle MusicPlaylist.

CREATE TABLE MusicPlaylist (
    SongId int,
    SongName text,
    Year int,
    Singer text,
    PRIMARY KEY ((SongId, Year), SongName)
);

Im obigen Beispiel, Tabelle MusicPlaylist,

  • SongId und Year sind der Partitionsschlüssel, und
  • SongName ist die Clusterspalte.
  • Die Daten werden auf der Grundlage des Songnamens gruppiert. In dieser Tabelle wird jedes Jahr eine neue Partition erstellt. Alle Songs des Jahres befinden sich auf demselben Knoten. Dieser Primärschlüssel ist für die Daten sehr nützlich.

Unser Datenabruf wird durch dieses Datenmodell schnell erfolgen.

Modellieren Sie Ihre Daten in Cassandra

Beim Modellieren Ihrer Abfragen sollten Sie Folgendes beachten:

Bestimmen Sie, welche Abfragen Sie unterstützen möchten

Bestimmen Sie zunächst, welche Abfragen Sie wünschen.

Brauchen Sie zum Beispiel?

  • Joins
  • Gruppiere nach
  • Filtern nach welcher Spalte usw.

Erstellen Sie eine Tabelle entsprechend Ihren Abfragen

Erstellen Sie eine Tabelle entsprechend Ihren Abfragen. Erstellen Sie eine Tabelle, die Ihren Anforderungen entspricht. Versuchen Sie, eine Tabelle so zu erstellen, dass eine Mindestanzahl an Partitionen gelesen werden muss.

In den drei folgenden Abschnitten wird dieses Prinzip auf die drei Beziehungstypen angewendet, die in nahezu jedem Schema vorkommen.

Umgang mit Eins-zu-Eins-Beziehungen in Cassandra

Eine Eins-zu-eins-Beziehung bedeutet, dass zwei Tabellen eine Eins-zu-eins-Entsprechung haben. Beispielsweise kann der Student nur einen Kurs anmelden, und ich möchte bei einem Studenten suchen, in welchem ​​Kurs ein bestimmter Student eingeschrieben ist.

In diesem Fall sollte Ihr Tabellenschema alle Details des Studenten enthalten, die dem jeweiligen Kurs entsprechen, wie etwa den Namen des Kurses, die Matrikelnummer des Studenten, den Namen des Studenten usw.

Eins-zu-eins-Beziehung in Cassandra
Eins-zu-eins-Beziehung in Cassandra

Das obige Diagramm zeigt eine einzelne Tabelle, die die Abfrage bedient, da ein Student genau einem Kurs zugeordnet ist.

CREATE TABLE Student_Course (
    Student_rollno int PRIMARY KEY,
    Student_name text,
    Course_name text
);

Da Student_rollno der Partitionsschlüssel ist, liest eine Suche anhand der Matrikelnummer genau eine Partition.

Umgang mit Eins-zu-Viele-Beziehungen in Cassandra

Eins-zu-viele-Beziehungen bedeuten, dass zwischen zwei Tabellen eine Eins-zu-viele-Korrespondenz vorliegt.

Beispielsweise kann ein Studiengang von vielen Studierenden studiert werden. Ich möchte alle Studenten durchsuchen, die einen bestimmten Kurs studieren.

Wenn ich also nach dem Kursnamen frage, erhalte ich viele Studentennamen, die einen bestimmten Kurs belegen werden.

Eins-zu-viele-Beziehung in Cassandra
Eins-zu-viele-Beziehung in Cassandra

Hierbei dient der Kursname als Partitionsschlüssel, sodass jeder Student eines Kurses in der gleichen Partition landet, und die Matrikelnummer dient als Clusterspalte, sodass jeder Student eine eigene Zeile bildet.

CREATE TABLE Student_Course (
    Course_name text,
    Student_rollno int,
    Student_name text,
    PRIMARY KEY (Course_name, Student_rollno)
);

Mit der folgenden Abfrage kann ich alle Studierenden für einen bestimmten Kurs abrufen.

SELECT * FROM Student_Course WHERE Course_name = 'Course Name';

Umgang mit Many-to-Many-Beziehungen in Cassandra

Viele-zu-viele-Beziehungen bedeuten, dass es viele-zu-viele-Korrespondenzen zwischen zwei Tabellen gibt.

Beispielsweise kann ein Studiengang von vielen Studierenden studiert werden und ein Student kann auch viele Studiengänge studieren.

Viele-zu-viele-Beziehung in Cassandra
Viele-zu-viele-Beziehung in Cassandra

Ich möchte alle Studenten durchsuchen, die einen bestimmten Kurs studieren. Außerdem möchte ich alle Kurse durchsuchen, die ein bestimmter Student studiert.

In diesem Fall verwende ich also zwei Tabellen, d. h. ich teile das Problem in zwei Fälle auf. Dies veranschaulicht die Duplizierungsregel am besten: Dieselben Fakten werden zweimal geschrieben, sodass jede Abfrage eine Partition liest.

Zunächst erstelle ich eine Tabelle, in der Sie Kurse eines bestimmten Studenten finden können.

CREATE TABLE Student_Course (
    Student_rollno int,
    Course_name text,
    Student_name text,
    PRIMARY KEY (Student_rollno, Course_name)
);

Mit der folgenden Abfrage kann ich alle Kurse eines bestimmten Studenten finden.

SELECT * FROM Student_Course WHERE Student_rollno = 101;

Zweitens werde ich eine Tabelle erstellen, anhand derer Sie sehen können, wie viele Studierende einen bestimmten Kurs studieren.

CREATE TABLE Course_Student (
    Course_name text,
    Student_rollno int,
    Student_name text,
    PRIMARY KEY (Course_name, Student_rollno)
);

Mit der folgenden Abfrage kann ich einen Studierenden in einem bestimmten Kurs finden.

SELECT * FROM Course_Student WHERE Course_name = 'Cassandra';

Beide Tabellen müssen jedes Mal beschrieben werden, wenn ein Student einem Kurs beitritt, normalerweise innerhalb eines einzigen Protokollierungsvorgangs, damit die beiden Kopien synchron bleiben.

gemeinsam Cassandra Fehler bei der Datenmodellierung

Die meisten mangelhaften Schemata wiederholen dieselben wenigen Fehler, und jedes tracEs ist eine Rückkehr zu einer Gewohnheit, die aus dem relationalen Design stammt.

  • Unbegrenzte Partitionen: Die Wahl eines Partitionsschlüssels wie beispielsweise eines Ländernamens führt dazu, dass Millionen von Zeilen in einer einzigen Partition zusammengefasst werden. Um die Partitionen in einer sinnvollen Größe zu halten, kann ein Zeitintervall hinzugefügt werden, beispielsweise (Land, Monat).
  • Schlüssel mit sehr niedriger Kardinalität: Ein Partitionsschlüssel mit nur wenigen möglichen Werten, wie beispielsweise einem Statusflag, konzentriert den gesamten Datenverkehr auf wenige Knoten und lässt die übrigen ungenutzt.
  • Um eine Abfrage zum Laufen zu bringen, verwenden Sie ALLOW FILTERING: Es durchsucht jede Partition und verschleiert dabei ein Modellierungsproblem. Falls eine Abfrage eine weitere Tabelle benötigt, benötigt das Schema diese.
  • Modellierung von Entitäten anstelle von Abfragen: Das Erstellen einer Tabelle für Studenten und einer Tabelle für Kurse und der anschließende Versuch, diese in der Anwendung zu verknüpfen, widerspricht dem Zweck des Designs.
  • Häufiges Löschen und Überschreiben: Jeder Löschvorgang erzeugt einen Tombstone, der gelesen und übersprungen werden muss, bis er durch die Komprimierung entfernt wird. Dies verlangsamt Lesevorgänge auf häufig genutzten Partitionen.

Durch das Vermeiden dieser Fehler bleibt das Schema im Einklang mit den oben auf dieser Seite genannten Regeln und den unten zusammengefassten relationalen Kontrasten.

Unterschied zwischen RDBMS und Cassandra Datenmodellierung

RDBMS Cassandra
Speichert Daten in normalisierter Form Speichert Daten in denormalisierter Form
Legacy-DBMS; strukturierte Daten Zeilenbasierter Speicher, dynamisch; strukturierte und unstrukturierte Daten
Schema ist um Entitäten und ihre Beziehungen herum konzipiert. Das Schema ist auf die Abfragen zugeschnitten, die die Anwendung ausführen wird.
Joins, GROUP BY und beliebige WHERE-Klauseln werden unterstützt. Keine Joins oder willkürliche Filterung; Abfragen müssen mit dem Primärschlüssel übereinstimmen.
Eine Tabelle dient üblicherweise vielen verschiedenen Abfragen. Eine Tabelle dient typischerweise einer Abfrage, daher werden Daten in mehreren Tabellen dupliziert.
Referenzielle Integrität wird durch Fremdschlüssel erzwungen Keine Fremdschlüssel; die Konsistenz zwischen duplizierten Tabellen liegt in der Verantwortung der Anwendung.

Diese Schemaentscheidungen werden in der Praxis angewendet in der Cassandra Tabelle und Schlüsselraum Tutorials.

Häufig gestellte Fragen

Streben Sie eine Partitionsgröße von unter 100 MB und etwa 100,000 Zeilen an. Größere Partitionen verlangsamen Lesevorgänge, verlängern Reparaturzeiten und erhöhen den Speicherdruck während der Komprimierung.

Der Partitionsschlüssel bestimmt, welcher Knoten die Zeile speichert. ClusterDie Spalten, die die Sortierreihenfolge der Zeilen innerhalb dieser Partition bestimmen, ermöglichen Bereichsabfragen wie beispielsweise Datumsabfragen.

Materialisierte Sichten automatisieren die Duplizierung, stellen aber weiterhin eine experimentelle Funktion mit bekannten Konsistenzproblemen dar. Die meisten Produktionsschemata behalten nach wie vor die zweite Tabelle der Anwendung bei.

KI kann Entitäten in Kandidatentabellen übersetzen, aber ein Cassandra Das Schema richtet sich nach den Abfragen, nicht nach den Entitäten. Geben Sie zuerst die Abfrageliste an und behandeln Sie die generierten Tabellen anschließend als Entwürfe, um sie anhand der Partitionsgröße zu validieren.

Anhand der Spaltenkardinalität und der erwarteten Zeilenanzahl kann die KI Schlüssel kennzeichnen, die wahrscheinlich Hotspots oder unbegrenzte Partitionen erzeugen. Bestätigen Sie die Warnung mit `nodetool tablehistograms`, sobald die realen Daten geladen sind.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: