2015-02-17 19 views
13

Ich benutze Cassandra zum ersten Mal in einer Web-App und ich habe ein Abfrageproblem. Hier ist meine tab:Cassandra Primärschlüssel Spalte kann nicht eingeschränkt werden

CREATE TABLE vote (
    doodle_id uuid, 
    user_id uuid, 
    schedule_id uuid, 
    vote int, 
    PRIMARY KEY ((doodle_id), user_id, schedule_id) 
); 

Auf jeder Anfrage, gebe ich meinen Partitionsschlüssel, doodle_id. Zum Beispiel kann ich ohne Probleme machen:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and user_id = 97a7378a-e1bb-4586-ada1-177016405142; 

Aber auf dem letzten Wunsch habe ich:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633; 

Ich habe die folgende Fehlermeldung:

Bad Request: PRIMARY KEY column "schedule_id" cannot be restricted (preceding column "user_id" is either not restricted or by a non-EQ relation) 

Ich bin neu mit Cassandra, aber korrigieren Sie mich, wenn ich falsch liege, in einem zusammengesetzten Primärschlüssel ist der erste Teil der PARTITION KEY, der Cassandra erlaubt zu wissen, wo man nach Daten suchen muss. Dann sind die anderen Teile CLUSTERING KEY, um Daten zu sortieren.

Aber ich verstehe immer noch nicht, warum meine erste Anfrage funktioniert und nicht die zweite?

Wenn jemand helfen könnte, wird es eine große Freude sein.

Antwort

9

In Cassandra sollten Sie Ihr Datenmodell für Ihre Abfragen entwerfen. Daher ist die richtige Methode, um Ihre zweite Abfrage (Abfragen von doodle_id und schedule_id, aber nicht notwendigerweise mit user_id) zu unterstützen, eine neue Tabelle zu erstellen, um diese bestimmte Abfrage zu behandeln. Diese Tabelle wird so ziemlich das gleiche, mit Ausnahme der Primärschlüssel etwas anders sein wird:

CREATE TABLE votebydoodleandschedule (
    doodle_id uuid, 
    user_id uuid, 
    schedule_id uuid, 
    vote int, 
    PRIMARY KEY ((doodle_id), schedule_id, user_id) 
); 

Nun ist diese Abfrage funktioniert:

SELECT * FROM votebydoodleandschedule 
WHERE doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 
AND schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633; 

Diese bekommt man um zu spezifizieren ALLOW FILTERING haben.Sich auf ALLOW FILTERING zu verlassen, ist nie eine gute Idee und ist sicherlich nicht etwas, das Sie in einem Produktionscluster tun sollten.

+0

Vielen Dank für die zwei Antworten! Ich verstehe jetzt ein bisschen besser, wie Cassandra arbeitet. So habe ich eine neue Tabelle erstellt, wie Sie erwähnt haben, um meine Anfrage zu bearbeiten, und es funktioniert jetzt gut. – Orodan

+0

und wenn ich> und

+0

@ParthTrivedi Um eine Bereichsabfrage für 'doodle_id' durchzuführen, müssen Sie eine neue Tabelle mit einem anderen Partitionsschlüssel erstellen (herausfinden, was für Ihre Daten sinnvoll ist). Dann könnten Sie einen Bereich von 'doodle_id' für einen bestimmten Partitionsschlüssel abfragen. – Aaron

3

Der Clusterschlüssel wird auch verwendet, um die Spalten innerhalb einer bestimmten Partition zu finden. Mit Ihrem Modell können Sie zur Abfrage von:

  • doodle_id
  • doodle_id/User_id
  • doodle_id/user_id/schedule_id
  • User_id mit ALLOW FILTERING
  • user_id/schedule_id mit ALLOW FILTERING

Sie können Ihren Primärschlüssel als Dateipfad doodle_id # 123/user_id # 456/schedule_id # 789 sehen, wo alle Daten werden im tiefsten Ordner gespeichert (zB Schedule_ID # 789). Wenn Sie abfragen, müssen Sie den Unterordner/Unterbaum angeben, von dem aus Sie suchen.

Ihre zweite Abfrage funktioniert nicht, da Spalten innerhalb der Partition organisiert sind. Cassandra kann keine fortlaufende Scheibe von Spalten in der Partition bekommen, weil sie verschachtelt sind.

Sie sollten die Primärschlüsselreihenfolge (doodle_id, schedule_id, user_id) invertieren, um Ihre Abfrage ausführen zu können.

Verwandte Themen