2012-07-05 49 views
6

的where子句的查詢我正在使用Cassandra 1.1.2我試圖將RDBMS應用程序轉換爲Cassandra。在我的RDBMS應用程序,我有如下表調用Table:Cassandra:包含大於或小於(< and >)

| Col1 | Col2 | Col3 | Col4 | 
  1. Col1中:字符串(主鍵)
  2. col2的:字符串(主鍵)
  3. COL3:BIGINT(指數)
  4. COL4 :Bigint

此表計數超過2億條記錄。最常用的查詢是這樣的:

Select * from table where col3 < 100 and col3 > 50; 

在卡桑德拉我用下面的語句來創建表:

create table table1 (primary_key varchar, col1 varchar, 
col2 varchar, col3 bigint, col4 bigint, primary key (primary_key)); 

create index on table1(col3); 

我改變了主鍵一個額外的列(計算我的應用程序內的鍵) 。 導入幾張唱片後,我試圖執行以下定製列表:

select * from table1 where col3 < 100 and col3 > 50; 

這一結果是:

Bad Request: No indexed columns present in by-columns clause with Equal operator 

查詢選擇COL1,COL2,COL3,COL4從表1,其中COL3 = 67件作品谷歌表示沒有辦法執行這種查詢。是對的嗎?任何建議如何創建這樣的查詢?

回答

6

Cassandra索引實際上並不支持順序訪問;請參閱http://www.datastax.com/docs/1.1/ddl/indexes以便快速瞭解它們的用途。但不要絕望;使用Cassandra(和許多其他NoSQL系統)的更經典的方式是非規範化,非規範化,非規範化。

可能你的情況使用經典鬥範圍模式,它可以讓你使用推薦RandomPartitioner並保持你的行以及周圍羣集分佈,同時還允許你的價值觀順序訪問一個好主意。在這種情況下,您的想法是,您將創建第二個動態列家族映射(bucketed和有序)col3值返回到相關的primary_key值。例如,如果您的col3值範圍從0到10^9並且分佈相當均勻,則您可能希望將它們分別放在1000個範圍爲10^6的桶中(最佳粒度級別取決於您的查詢類型需要,您擁有的數據種類,查詢往返時間等)。例如架構cql3:

CREATE TABLE indexotron (
    rangestart int, 
    col3val int, 
    table1key varchar, 
    PRIMARY KEY (rangestart, col3val, table1key) 
); 

當插入table1,你應該在indexotron插入相應一行,rangestart = int(col3val/1000000)。然後,當需要使用col3> X枚舉table1中的所有行時,您需要查詢多達1000個桶,其中indexotron,但其中的所有col3val將被排序。例如查詢找到所有table1.primary_key值,其中table1.col3 < 4021

SELECT * FROM indexotron WHERE rangestart = 0 ORDER BY col3val; 
SELECT * FROM indexotron WHERE rangestart = 1000 ORDER BY col3val; 
SELECT * FROM indexotron WHERE rangestart = 2000 ORDER BY col3val; 
SELECT * FROM indexotron WHERE rangestart = 3000 ORDER BY col3val; 
SELECT * FROM indexotron WHERE rangestart = 4000 AND col3val < 4021 ORDER BY col3val; 
+0

'select count(*)'也可能有用,FWIW ... – rogerdpack 2018-02-12 22:14:33

0

如果COL3總是已知的小值/範圍,你可以用一個簡單的表也映射回初始表就完事了,例如:

create table table2 (col3val int, table1key varchar, 
    primary key (col3val, table1key)); 

,並使用

insert into table2 (col3val, table1key) values (55, 'foreign_key'); 
insert into table2 (col3val, table1key) values (55, 'foreign_key3'); 
select * from table2 where col3val = 51; 
select * from table2 where col3val = 52; 
... 

也許OK,如果你不具有太大的範圍。 (你可以得到與你的二級指數相同的效果,但是二級指標並不強烈推薦?)。理論上可以將其「在客戶端本地」並行化。

看起來「Cassandra的方式」是有一些像「userid」這樣的關鍵字,並將其用作「所有查詢」的第一部分,因此您可能需要重新考慮數據模型,然後您可以查詢select * from table1 where userid='X' and col3val > 3,它可以work(假設col3val上有一個集羣密鑰)。

相關問題