首页 文章

Cassandra:使用where子句查询包含更大或更小的(<和>)

提问于
浏览
7

我正在使用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 回答

  • 7

    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的示例模式:

    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 的存储桶,但其中的所有_1389113都将被排序 . 用于查找 table1.col3 < 4021 的所有 table1.primary_key 值的示例查询:

    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

    如果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它"locally on the client side" .

    似乎"Cassandra way"有一些像"userid"这样的关键,你使用它作为"all your queries"的第一部分,所以你可能需要重新考虑你的数据模型,那么你可以像 select * from table1 where userid='X' and col3val > 3 那样查询它可以work(假设col3val上有一个聚类键) .

相关问题