2016-08-08 11 views
1

Ich habe eine Tabelle mit diesemund Klausel in cql cassandra

Schema erstellt
CREATE TABLE iplocation (
    "idIPLocation" uuid, 
    "fromIP" bigint, 
    "toIP" bigint, 
    "idCity" uuid, 
    "idCountry" uuid, 
    "idProvince" uuid, 
    "isActive" boolean, 
    PRIMARY KEY ("idIPLocation", "fromIP", "toIP") 
) 

und eingefügt einige Datensätze in it! jetzt will ich

select * from iplocation where "toIP" <= 3065377522 and "fromIP" >= 3065377522 ALLOW FILTERING; 

einen Datensatz wie diese holen, aber seine gibt mir einen Fehler von

A column of a clustering key can be restricted only if the preceding one is restricted by an Equal relation. 
You need to restrict fromIP before restrict toIP. 

aber wenn ich nur

select * from iplocation where "toIP" <= 3065377522 ALLOW FILTERING; 

tun wollen Sie sagt noch

column of a clustering key can be restricted only if the preceding 
    one is restricted by an Equal relation. 
You need to restrict 
    fromIP before restrict toIP. 

ich kann nicht figu Was ist das Problem?

Antwort

3

Sie missbrauchen Partition Key-Konzept. In Ihrem Fall ist der Partitionsschlüssel idIPLocation Cassandra verwenden Sie diesen Schlüssel, um zu wissen, in welche Partition Daten geschrieben oder gelesen werden. In Ihrer Select-Anweisung müssen Sie also den Partitionsschlüssel angeben. Dann können Sie Daten in der angegebenen Partition filtern, indem Sie fromIP, toIP angeben.

Sie haben vier Lösungen: 1) Wählen Sie eine bessere Partition Schlüssel: Sie können zum Beispiel followinf Partition Schlüsselklausel verwenden: PRIMARY KEY ("toIP"). Aber in Ihrem Fall, ich denke, diese Lösung wird nicht funktionieren, weil Sie Daten auch durch idIPLocation abfragen möchten.

2) denormalisieren: eine neue Tabelle mit der gleichen Datenstruktur hinzufügen, aber eine andere Partition Schlüssel wie folgt: CREATE TABLE backup_advertyze.iplocation ( "idIPLocation" uuid, "fromIP" bigint, "toIP" bigint, "idCity" uuid, "idCountry" uuid, "idProvince" uuid, "isActive" boolean, PRIMARY KEY ("idIPLocation", "fromIP", "toIP") ); CREATE TABLE backup_advertyze.iplocationbytoip ( "idIPLocation" uuid, "fromIP" bigint, "toIP" bigint, "idCity" uuid, "idCountry" uuid, "idProvince" uuid, "isActive" boolean, PRIMARY KEY ("toIP", "fromIP") );

mit dieser Struktur Sie diese Abfrage select * from iplocationbytoip where "toIP" <= 3065377522 and "fromIP" >= 3065377522 ausführen können. Aber mit dieser Lösung müssen Sie verdoppelt in zwei Tabellen pflegen

3) Verwendung materialisierte Ansicht: Dies ist das gleiche Konzept wie 2) aber Sie haben Daten in einer Tabelle zu halten, statt zwei: `TABLE backup_advertyze CREATE. iplocation ( "idIPLocation" UUID, "fromIP" Bigint, "ToIP" Bigint, "idCity" UUID, "idCountry" UUID, "idProvince" UUID, "isActive" boolean, PRIMARY KEY ("idIPLocation "," vonIP "," bisIP ") );

CREATE MATERIALIZED VIEW backup_advertyze.iplocationbytoip AS SELECT * FROM backup_advertyze.iplocation WHERE idIPLocation IS NOT NULL UND fromIP IS NOT NULL UND ToIP IS NOT NULL PRIMARY KEY (ToIP, fromip, idiplocation); `

4) Die einfachste Lösung, aber ich empfehlen nicht aufgrund performences Probleme abfragen verwenden secondary indexes:

CREATE INDEX iplocationfromindex ON backup_advertyze.iplocation(fromip);

können Sie Ihre Abfrage select * from iplocation where "toIP" <= 3065377522 and "fromIP" >= 3065377522 ALLOW FILTERING; ausführen.

Hoffe, das kann Ihnen helfen.

1

Zunächst einmal ist die Verwendung der ALLOW FILTERING Direktive schrecklich ineffizient, und ihre Verwendung wird als ein Anti-Pattern betrachtet. Wenn Sie feststellen müssen, dass Sie es verwenden müssen, um eine Abfrageanforderung zu erfüllen, sollten Sie stattdessen eine neue Tabelle erstellen, die besser zu Ihrer Abfrage passt. Vielleicht eine, die Ihre Partitionsschlüssel besser für den Datenabruf nutzt. nur

select * from implication 
where "toIP" <= 3065377522 and "fromIP" >= 3065377522 ALLOW FILTERING; 

Dies schlägt fehl, weil Cassandra verwenden nicht gleich Bedingungen (> =>, <, < =) auf einer einzigen Spalte, und es hat die letzte sein.

select * from implication 
where "toIP" <= 3065377522 ALLOW FILTERING; 

Dies schlägt mit der gleichen Fehlermeldung fehl, weil es erkennt, dass Sie aktiv versuchen, Cassandra davon abzuhalten, das zu tun, was es am besten kann. Und das ist eine einzelne Zeile oder ein zusammenhängender Bereich von geordneten Reihen von der Festplatte gelesen. Im Wesentlichen fordern Sie es auf, zufällige Lesevorgänge auszuführen, da es jeden Knoten in Ihrem Cluster überprüfen muss, um diese Abfrage zu erfüllen. Da Cassandra so konzipiert ist, dass es großräumig unterstützt wird, könnte dies viel Zeit für das Netzwerk in Ihre Abfrage-Gleichung einbringen ... etwas, vor dem es Sie zu retten versucht.

Um dieses Problem zu lösen, würde ich die Tabelle mit einem entsprechenden Partitionsschlüssel (wie oben erwähnt) eine einzelne IP-Adresse Spalte und eine von/zu Spalte ... alles ein Teil des Schlüssels. Es würde wie folgt aussehen:

CREATE TABLE iplocation (
    idIPLocation uuid, 
    IP bigint, 
    fromTo text, 
    idCity uuid, 
    idCountry uuid, 
    idProvince uuid, 
    isActive boolean, 
    PRIMARY KEY (idIPLocation, IP, fromTo) 
); 

Jetzt im Wesentlichen Sie Ihre Daten speichern, zweimal, Sie einen Start geben und IP-Bereich endet. Die Zeilen werden durch einen F oder T als Clustering-Schlüssel unterschieden, um Ihnen zu sagen, welche die "Von IP" ist und welche die "Zu IP" ist.

[email protected]:stackoverflow> SELECT * FROm implication 
    WHERE idiplocation=76080f76-92f7-4d25-a531-a44c38ff38a7 
    AND IP>=10000 AND IP<=3065377522; 

idiplocation       | ip  | fromto | idcity        | idcountry       | idprovince       | isactive 
--------------------------------------+----------+--------+--------------------------------------+--------------------------------------+--------------------------------------+---------- 
76080f76-92f7-4d25-a531-a44c38ff38a7 | 10001 |  F | 6921a08b-c156-428e-8d4f-b371ff13f073 | f33bd5ed-b9b3-419b-99ab-ac2a7c87ba55 | 5a13cfcc-382e-418a-aeae-309f43671336 |  True 
76080f76-92f7-4d25-a531-a44c38ff38a7 | 10480101 |  T | 6921a08b-c156-428e-8d4f-b371ff13f073 | f33bd5ed-b9b3-419b-99ab-ac2a7c87ba55 | 5a13cfcc-382e-418a-aeae-309f43671336 |  True 

(2 rows) 

Dies ist ähnlich, wie ich Probleme modellieren, wo Datenpunkte haben eine Reihe von sowohl einer Start- und Endzeit an. Während Ihre Endlösung wahrscheinlich anders sein wird, ist der Modellierungsmechanismus hier etwas, das für Sie funktionieren könnte.

+0

danke für diese detaillierte beantwortet, aber ich habe keine idiplocation ich nur beschränken, ip zu verwenden, um jede lösung zu suchen? – maq

Verwandte Themen