我正在使用Cassandra 1.1.2我正在尝试将RDBMS应用程序转换为Cassandra。在我的RDBMS应用程序中,我有一个名为table1的表:
| Col1 | Col2 | Col3 | Col4 |
此表包含超过2亿条记录。最常用的查询类似于:
Select * from table where col3 < 100 and col3 > 50;
在Cassandra中,我使用以下语句创建表:
create table table1 (primary_key varchar, col1 varchar,
col2 varchar, col3 bigint, col4 bigint, primary key (primary_key));
create index on table1(col3);
我将主键更改为一个额外的列(我计算了我的应用程序中的键)。 导入几条记录后,我尝试执行以下cql:
select * from table1 where col3 < 100 and col3 > 50;
结果是:
Bad Request: No indexed columns present in by-columns clause with Equal operator
查询从table1选择col1,col2,col3,col4,其中col3 = 67
Google表示无法执行此类查询。是对的吗?有关如何创建此类查询的任何建议吗?答案 0 :(得分:7)
Cassandra索引实际上并不支持顺序访问;请参阅http://www.datastax.com/docs/1.1/ddl/indexes,以便快速解释它们的用途。但不要绝望;使用Cassandra(以及许多其他NoSQL系统)的更经典的方法是非规范化,非规范化,非规范化。
在您的情况下,可能是一个好主意,可以使用经典的桶范围模式,它允许您使用推荐的RandomPartitioner并保持您的行在群集中良好分布,同时仍然允许顺序访问你的价值观。在这种情况下的想法是,您将第二个动态列家庭映射(分段和有序)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&gt;枚举table1
中的所有行时X,您需要查询最多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;
答案 1 :(得分: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;
...
或者
select * from table2 where col3val in (51, 52, ...);
如果没有太大的范围,也许可以。 (您也可以使用辅助索引获得相同的效果,但不强烈建议使用辅助索引?)。从理论上讲,parallelize它也可以“在客户端本地”。
似乎“Cassandra方式”是拥有一些像“userid”这样的键,你将它用作“所有查询”的第一部分,这样你可能需要重新考虑你的数据模型,然后你可以查询{ {1}}它可以work(假设col3val上有一个聚类键)。