我正在使用Cassandra 1.1.2我正在尝试将RDBMS应用程序转换为Cassandra . 在我的RDBMS应用程序中,我有以下表名为table1:
| Col1 | Col2 | Col3 | Col4 |
-
Col1:String(主键)
-
Col2:String(主键)
-
Col3:Bigint(索引)
-
Col4:Bigint
该表计有超过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
查询 select col1,col2,col3,col4 from table1 where col3 = 67 有效
谷歌表示无法执行这类查询 . 是对的吗?有什么建议如何创建这样的查询?
2 回答
Cassandra索引实际上不支持顺序访问;请参阅http://www.datastax.com/docs/1.1/ddl/indexes,以便快速解释它们的用途 . 但不要绝望;使用Cassandra(以及许多其他NoSQL系统)的更经典的方法是非规范化,非规范化,非规范化 .
在您的情况下,使用经典的桶范围模式可能是一个好主意,它允许您使用推荐的RandomPartitioner并使您的行在群集中保持良好分布,同时仍允许顺序访问您的值 . 在这种情况下的想法是,您将第二个动态columnfamily映射(bucketed和ordered)
col3
值返回到相关的primary_key
值 . 例如,如果您的col3
值的范围从0到10 ^ 9并且分布相当均匀,您可能希望将它们放在1000个桶中,每个桶的范围为10 ^ 6(最佳粒度级别取决于您的查询类型)需要,你有的数据类型,查询往返时间等) . cql3的示例模式:插入
table1
时,应在indexotron
中插入相应的行,其中包含rangestart = int(col3val / 1000000)
. 然后,当您需要使用col3> X枚举table1
中的所有行时,您需要查询最多1000个indexotron
的存储桶,但其中的所有_1389113都将被排序 . 用于查找table1.col3 < 4021
的所有table1.primary_key
值的示例查询:如果col3始终是已知的小值/范围,那么您可以使用更简单的表来逃避,该表也会映射回初始表,例如:
并使用
要么
如果你不强烈推荐,可能还可以吗?) . 理论上也可以parallelize它"locally on the client side" .
似乎"Cassandra way"有一些像"userid"这样的关键,你使用它作为"all your queries"的第一部分,所以你可能需要重新考虑你的数据模型,那么你可以像
select * from table1 where userid='X' and col3val > 3
那样查询它可以work(假设col3val上有一个聚类键) .