Unterschied zwischen Partitionsschlüssel, zusammengesetztem Schlüssel und Clustering-Schlüssel in Cassandra?


523

Ich habe Artikel im Internet gelesen, um die Unterschiede zwischen den folgenden keyTypen zu verstehen . Aber es scheint mir nur schwer zu verstehen. Beispiele werden definitiv dazu beitragen, das Verständnis zu verbessern.

primary key,
partition key, 
composite key 
clustering key

23
Ich habe diesen Artikel gefunden, der viele detaillierte Erklärungen zu diesen Konzepten enthält.
Mynkow

In diesem Artikel wird auch klar auf diese Begriffe hingewiesen.
duong_dajgja

@duong_dajgja URL, die Sie oben geteilt haben, ist fehlerhaft. Können Sie bitte einen Kommentar mit einer gültigen / nützlichen URL bearbeiten?
RealPK

@realPK Der Link ist irgendwie weg. Aber ich habe hier einen anderen Link für Sie gefunden quora.com/… .
duong_dajgja

Antworten:


1172

Es gibt viel Verwirrung darüber, ich werde versuchen, es so einfach wie möglich zu machen.

Der Primärschlüssel ist ein allgemeines Konzept zur Angabe einer oder mehrerer Spalten, die zum Abrufen von Daten aus einer Tabelle verwendet werden.

Der Primärschlüssel kann EINFACH sein und sogar inline deklariert werden:

 create table stackoverflow_simple (
      key text PRIMARY KEY,
      data text      
  );

Das bedeutet, dass es aus einer einzelnen Spalte besteht.

Der Primärschlüssel kann aber auch COMPOSITE (auch bekannt als COMPOUND ) sein, das aus mehreren Spalten generiert wird.

 create table stackoverflow_composite (
      key_part_one text,
      key_part_two int,
      data text,
      PRIMARY KEY(key_part_one, key_part_two)      
  );

In einer Situation des COMPOSITE- Primärschlüssels heißt der "erste Teil" des Schlüssels PARTITION KEY (in diesem Beispiel ist key_part_one der Partitionsschlüssel) und der zweite Teil des Schlüssels ist der CLUSTERING KEY (in diesem Beispiel key_part_two ).

Beachten Sie, dass sowohl der Partitions- als auch der Clustering-Schlüssel aus mehreren Spalten bestehen können.

 create table stackoverflow_multiple (
      k_part_one text,
      k_part_two int,
      k_clust_one text,
      k_clust_two int,
      k_clust_three uuid,
      data text,
      PRIMARY KEY((k_part_one, k_part_two), k_clust_one, k_clust_two, k_clust_three)      
  );

Hinter diesen Namen ...

  • Der Partitionsschlüssel ist für die Datenverteilung auf Ihre Knoten verantwortlich.
  • Der Clustering-Schlüssel ist für die Datensortierung innerhalb der Partition verantwortlich.
  • Der Primärschlüssel entspricht dem Partitionsschlüssel in einer Einzelfeldschlüsseltabelle (dh einfach ).
  • Der zusammengesetzte / zusammengesetzte Schlüssel ist nur ein beliebiger mehrspaltiger Schlüssel

Weitere Verwendungsinformationen: DATASTAX-DOKUMENTATION


Beispiele für kleine Verwendung und Inhalte
EINFACHER SCHLÜSSEL:

insert into stackoverflow_simple (key, data) VALUES ('han', 'solo');
select * from stackoverflow_simple where key='han';

Tabelleninhalt

key | data
----+------
han | solo

COMPOSITE / COMPOUND KEY kann "breite Zeilen" abrufen (dh Sie können nur nach dem Partitionsschlüssel abfragen, selbst wenn Sie Clustering-Schlüssel definiert haben).

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 9, 'football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 10, 'ex-football player');
select * from stackoverflow_composite where key_part_one = 'ronaldo';

Tabelleninhalt

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      ronaldo |           10 | ex-football player

Sie können jedoch mit allen Schlüsseln (sowohl Partition als auch Clustering) abfragen ...

select * from stackoverflow_composite 
   where key_part_one = 'ronaldo' and key_part_two  = 10;

Abfrageausgabe

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |           10 | ex-football player

Wichtiger Hinweis: Der Partitionsschlüssel ist der Mindestspezifizierer, der zum Ausführen einer Abfrage mit a erforderlich ist where clause. Wenn Sie einen zusammengesetzten Partitionsschlüssel haben, wie folgt

z.B: PRIMARY KEY((col1, col2), col10, col4))

Sie können eine Abfrage nur durchführen, indem Sie mindestens col1 und col2 übergeben. Dies sind die beiden Spalten, die den Partitionsschlüssel definieren. Die "allgemeine" Regel für die Abfrage lautet, dass Sie mindestens alle Partitionsschlüsselspalten übergeben müssen. Anschließend können Sie optional jeden Clusterschlüssel in der angegebenen Reihenfolge hinzufügen.

Die gültigen Abfragen sind also ( ohne Sekundärindizes ).

  • col1 und col2
  • col1 und col2 und col10
  • col1 und col2 und col10 und col 4

Ungültig:

  • col1 und col2 und col4
  • alles, was nicht sowohl col1 als auch col2 enthält

Hoffe das hilft.


7
Wie ich geschrieben habe - << Die "allgemeine" Regel, um eine Abfrage durchzuführen, ist, dass Sie mindestens alle Partitionsschlüsselspalten übergeben müssen, dann können Sie jeden Schlüssel in der Reihenfolge hinzufügen, in der sie festgelegt wurden. >> - da col10 zuvor definiert wurde col4 Sie müssen es übergeben, um auch nach col4
Carlo Bertuccini

2
Sie können Sekundärindizes hinzufügen, aber das bedeutet nicht, dass Sie "jede" cql-Abfrage ausführen können - und mehr: Bevor Sie einen Sekundärindex erstellen, sollten Sie bis 10 ... 000 zählen ..... :)
Carlo Bertuccini

2
Sekundärindizes werden als lokale Indizes implementiert - sie werden nicht im Cluster verteilt. Jeder Knoten des Clusters ist für das Speichern von Sekundärindizes von Daten verantwortlich, deren Eigentümer er ist. Aus diesem Grund kann eine Abfrage auf sec.index alle Knoten im Cluster betreffen
Carlo Bertuccini

5
Das hat mich ein paar Tage verwirrt, danke für diese Antwort, jetzt kann ich das Datenmodell in meinem Kopf aufbauen.
Roger Dwan

2
Beeindruckend. Du hast mir nur Stunden oder Tage gerettet! Danke, geniale Erklärung.
Andre Garcia

128

Das Hinzufügen einer zusammenfassenden Antwort als akzeptierte Antwort ist ziemlich lang. Die Begriffe "Zeile" und "Spalte" werden im Kontext von CQL verwendet, nicht wie Cassandra tatsächlich implementiert wird.

  • Ein Primärschlüssel identifiziert eine Zeile eindeutig.
  • Ein zusammengesetzter Schlüssel ist ein Schlüssel, der aus mehreren Spalten besteht.
  • Ein Partitionsschlüssel ist die primäre Suche, um eine Reihe von Zeilen zu finden, dh eine Partition.
  • Ein Clustering-Schlüssel ist der Teil des Primärschlüssels, der nicht der Partitionsschlüssel ist (und die Reihenfolge innerhalb einer Partition definiert).

Beispiele:

  • PRIMARY KEY (a): Der Partitionsschlüssel ist a.
  • PRIMARY KEY (a, b): Der Partitionsschlüssel ist a, der Clustering-Schlüssel ist b.
  • PRIMARY KEY ((a, b)): Der zusammengesetzte Partitionsschlüssel ist (a, b).
  • PRIMARY KEY (a, b, c): Der Partitionsschlüssel ist a, der zusammengesetzte Clustering-Schlüssel ist (b, c).
  • PRIMARY KEY ((a, b), c): Der zusammengesetzte Partitionsschlüssel ist (a, b), der Clustering-Schlüssel ist c.
  • PRIMARY KEY ((a, b), c, d): Der zusammengesetzte Partitionsschlüssel ist (a, b), der zusammengesetzte Clustering-Schlüssel ist (c, d).

15

In Cassandra sorgt der Unterschied zwischen Primärschlüssel, Partitionsschlüssel, zusammengesetztem Schlüssel und Clustering-Schlüssel immer für Verwirrung. Ich werde dies im Folgenden erläutern und in Beziehung zueinander setzen. Wir verwenden CQL (Cassandra Query Language) für den Zugriff auf die Cassandra-Datenbank. Hinweis: - Die Antwort entspricht der aktualisierten Version von Cassandra. Primärschlüssel :-

In Cassandra gibt es zwei verschiedene Möglichkeiten, den Primärschlüssel zu verwenden.

CREATE TABLE Cass (
    id int PRIMARY KEY,
    name text 
);

Create Table Cass (
   id int,
   name text,
   PRIMARY KEY(id) 
);

In CQL spielt die Reihenfolge eine Rolle, in der Spalten für den PRIMARY KEY definiert werden. Die erste Spalte des Schlüssels wird als Partitionsschlüssel mit der Eigenschaft bezeichnet, dass alle Zeilen, die denselben Partitionsschlüssel verwenden (auch tabellenübergreifend), auf demselben physischen Knoten gespeichert sind. Das Einfügen / Aktualisieren / Löschen von Zeilen, die denselben Partitionsschlüssel für eine bestimmte Tabelle verwenden, erfolgt atomar und isoliert. Beachten Sie, dass es möglich ist, einen zusammengesetzten Partitionsschlüssel zu haben, dh einen Partitionsschlüssel, der aus mehreren Spalten besteht, wobei ein zusätzlicher Satz von Klammern verwendet wird, um zu definieren, welche Spalten den Partitionsschlüssel bilden.

Partitionierung und Clustering Die Definition von PRIMARY KEY besteht aus zwei Teilen: dem Partitionsschlüssel und den Clustering-Spalten. Der erste Teil wird dem Zeilenschlüssel der Speicher-Engine zugeordnet, während der zweite Teil zum Gruppieren von Spalten in einer Zeile verwendet wird.

CREATE TABLE device_check (
  device_id   int,
  checked_at  timestamp,
  is_power    boolean,
  is_locked   boolean,
  PRIMARY KEY (device_id, checked_at)
);

Hier ist device_id der Partitionsschlüssel und checked_at ist cluster_key.

Wir können auch mehrere Clusterschlüssel sowie Partitionsschlüssel haben, was von der Deklaration abhängt.


6
Sie hätten Ihren Quellen etwas Anerkennung zollen
Christophe Roussy

11

Primärschlüssel : Besteht aus Partitionsschlüsseln [und optionalen Clusterschlüsseln (oder Spalten)].
Partitionsschlüssel : Der Hashwert des Partitionsschlüssels wird verwendet, um den spezifischen Knoten in einem Cluster zum Speichern der Daten zu bestimmen.
Clustering-Schlüssel : Wird verwendet Sortieren Sie die Daten in jeder der Partitionen (oder dem verantwortlichen Knoten und seinen Replikaten).

Zusammengesetzter Primärschlüssel : Wie oben erwähnt, sind die Clustering-Schlüssel in einem Primärschlüssel optional. Wenn sie nicht erwähnt werden, handelt es sich um einen einfachen Primärschlüssel. Wenn Clustering-Schlüssel erwähnt werden, handelt es sich um einen zusammengesetzten Primärschlüssel.

Zusammengesetzter Partitionsschlüssel : Die Verwendung nur einer Spalte als Partitionsschlüssel kann zu Problemen mit großen Zeilen führen (abhängig von der Anwendungsfall- / Datenmodellierung). Daher wird der Partitionsschlüssel manchmal als eine Kombination aus mehr als einer Spalte angegeben.

In Bezug auf die Verwirrung darüber, welche obligatorisch ist , welche übersprungen werden kann usw.hilft es, sich Cassandra als eine riesige HashMap vorzustellen . In einer HashMap können Sie die Werte also nicht ohne den Schlüssel abrufen.
Hier spielen die Partitionstasten die Rolle dieses Schlüssels. Für jede Abfrage müssen sie also angegeben werden. Ohne welche Cassandra nicht weiß, nach welchem ​​Knoten sie suchen soll.
Die Clustering-Schlüssel (Spalten, die optional sind) helfen dabei, Ihre Abfragesuche weiter einzugrenzen, nachdem Cassandra den spezifischen Knoten (und seine Replikate) ermittelt hat, der für diesen bestimmten Partitionsschlüssel verantwortlich ist .


5

Kurz gesagt:

Der Partitionsschlüssel ist nichts anderes als eine Identifikation für eine Zeile. Diese Identifikation ist meistens die einzelne Spalte (als Primärschlüssel bezeichnet ), manchmal eine Kombination mehrerer Spalten (als zusammengesetzter Partitionsschlüssel bezeichnet ).

Der Clusterschlüssel ist nichts anderes als Indizieren und Sortieren . Clusterschlüssel hängen von wenigen Dingen ab:

  1. Welche Spalten verwenden Sie in der where-Klausel mit Ausnahme der Primärschlüsselspalten?

  2. Wenn Sie sehr große Aufzeichnungen haben, kann ich das Datum für eine einfache Verwaltung aufteilen. Beispiel, ich habe Daten von 1 Million Aufzeichnungen eines Landkreises. Für eine einfache Verwaltung gruppiere ich Daten basierend auf dem Status und nach dem PIN-Code und so weiter.


3
Partitionsschlüssel ist KEINE Identifikation für eine Zeile ... er identifiziert eine Reihe von Zeilen, die alle den gleichen Partitionsschlüssel haben
wmac

1

Es ist erwähnenswert, dass Sie diese Lose wahrscheinlich häufiger verwenden werden als in ähnlichen Konzepten in der relationalen Welt (zusammengesetzte Schlüssel).

Beispiel - Angenommen, Sie müssen die letzten N Benutzer finden, die kürzlich der Benutzergruppe X beigetreten sind. Wie würden Sie dies effizient tun, wenn in diesem Fall Lesevorgänge vorherrschen? So (aus dem offiziellen Cassandra-Führer ):

CREATE TABLE group_join_dates (
    groupname text,
    joined timeuuid,
    join_date text,
    username text,
    email text,
    age int,
    PRIMARY KEY ((groupname, join_date), joined)
) WITH CLUSTERING ORDER BY (joined DESC)

Hier ist der Partitionierungsschlüssel selbst zusammengesetzt und der Clustering-Schlüssel ist ein Beitrittsdatum. Der Grund, warum ein Clustering-Schlüssel ein Beitrittsdatum ist, besteht darin, dass die Ergebnisse bereits sortiert (und gespeichert, wodurch die Suche schnell erfolgt). Aber warum verwenden wir einen zusammengesetzten Schlüssel zum Partitionieren des Schlüssels ? Weil wir immer so wenig Partitionen wie möglich lesen wollen . Wie hilft es , join_date dort einzufügen ? Jetzt befinden sich Benutzer derselben Gruppe und desselben Beitrittsdatums in einer einzelnen Partition! Dies bedeutet, dass wir immer so wenige Partitionen wie möglich lesen (zuerst mit der neuesten beginnen, dann zu älteren wechseln und so weiter, anstatt zwischen ihnen zu springen).

In extremen Fällen müssten Sie auch den Hash eines join_date anstelle eines join_date verwenden. Wenn Sie also die letzten 3 Tage abfragen, verwenden diese häufig denselben Hash und sind daher auf derselben Partition verfügbar!


0

Der Primärschlüssel in Cassandra besteht normalerweise aus zwei Teilen - Partitionsschlüssel und Clustering-Spalten.

Primärschlüssel ((Partitionsschlüssel), Clustering-Spalte)

Partitionsschlüssel - Der erste Teil des Primärschlüssels. Das Hauptziel eines Partitionsschlüssels besteht darin, den Knoten zu identifizieren, auf dem die bestimmte Zeile gespeichert ist.

CREATE TABLE phone_book (phone_num int, Namenstext, age int, Stadttext, PRIMARY KEY ((phone_num, name), age);

Hier ist (phone_num, name) der Partitionsschlüssel. Beim Einfügen der Daten wird der Hashwert des Partitionsschlüssels generiert und dieser Wert entscheidet, in welchen Knoten die Zeile gehen soll.

Stellen Sie sich einen 4-Knoten-Cluster vor. Jeder Knoten verfügt über einen Bereich von Hash-Werten, die gespeichert werden können. (Schreiben) INSERT INTO phone_book VALUES (7826573732, 'Joey', 25, 'New York');

Jetzt wird der Hash-Wert des Partitionsschlüssels vom Cassandra-Partitionierer berechnet. Sagen wir, Hash-Wert (7826573732, 'Joey') → 12, jetzt wird diese Zeile in Knoten C eingefügt.

(Lesen) SELECT * FROM phone_book WHERE phone_num = 7826573732 und name = 'Joey';

Nun wird wieder der Hash-Wert des Partitionsschlüssels (7826573732, 'Joey') berechnet, in unserem Fall 12, der sich in Knoten C befindet, von dem aus das Lesen erfolgt.

  1. Clustering-Spalten - Zweiter Teil des Primärschlüssels. Der Hauptzweck von Clustering-Spalten besteht darin, die Daten in einer sortierten Reihenfolge zu speichern. Standardmäßig ist die Reihenfolge aufsteigend.

Abhängig von der zu lösenden Abfrage kann ein Primärschlüssel mehr als einen Partitionsschlüssel und Clustering-Spalten enthalten.

primary_key ((pk1, pk2), Spalte 1, Spalte 2)


-3

Beim Datenbankdesign besteht ein zusammengesetzter Schlüssel aus einer Reihe von Superschlüsseln, die nicht minimal sind.

Ein zusammengesetzter Schlüssel ist eine Menge, die einen zusammengesetzten Schlüssel und mindestens ein Attribut enthält, das kein Superschlüssel ist

Gegebene Tabelle: MITARBEITER {Mitarbeiter-ID, Vorname, Nachname}

Mögliche Superkeys sind:

{employee_id}
{employee_id, firstname}
{employee_id, firstname, surname}

{employee_id} ist der einzige minimale Superkey, was ihn auch zum einzigen Kandidatenschlüssel macht - da {Vorname} und {Nachname} keine Eindeutigkeit garantieren. Da ein Primärschlüssel als ausgewählter Kandidatenschlüssel definiert ist und in diesem Beispiel nur ein Kandidatenschlüssel vorhanden ist, ist {employee_id} der minimale Superkey, der einzige Kandidatenschlüssel und der einzig mögliche Primärschlüssel.

Die vollständige Liste der zusammengesetzten Schlüssel lautet:

{employee_id, firstname}
{employee_id, surname}
{employee_id, firstname, surname}

Der einzige zusammengesetzte Schlüssel ist {employee_id, Vorname, Nachname}, da dieser Schlüssel einen zusammengesetzten Schlüssel ({employee_id, Vorname}) und ein Attribut enthält, das kein Superkey ({Nachname}) ist.


Völlig irrelevant für die gestellte Frage. Bitte bearbeiten Sie die Antwort auf die im Zusammenhang mit Cassandra gestellten Adressschlüssel, keine allgemeine Erklärung. TY.
RealPK
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.