使用cql在Cassandra中选择特定记录

时间:2014-11-13 04:38:24

标签: cassandra cql cqlsh

这是我使用的架构:

CREATE TABLE playerInfo (
key text,
column1 bigint,
column2 bigint,
column3 bigint,
column4 bigint,
column5 text,
value bigint,
PRIMARY KEY (key, column1, column2, column3, column4, column5)
)   
WITH COMPACT STORAGE AND
bloom_filter_fp_chance=0.010000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.000000 AND
gc_grace_seconds=864000 AND
read_repair_chance=0.100000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
compaction={'class': 'SizeTieredCompactionStrategy'} AND
compression={'sstable_compression': 'SnappyCompressor'};

注意我使用复合键。还有一个这样的记录:

 key      | column1    | column2 | column3  | column4 | column5           | value
----------+------------+---------+----------+---------+--------------------------------------------------+-------
 Kitty    | 1411       |       3 | 713      |       4 |   American        |     1

cqlsh中,如何选择它?我尝试使用:

cqlsh:game> SELECT * FROM playerInfo WHERE KEY = 'Kitty' AND column5 = 'American';

但输出是:

Bad Request: PRIMARY KEY part column5 cannot be restricted (preceding part column4 is either not restricted or by a non-EQ relation)

然后我该如何选择这样的细胞?

2 个答案:

答案 0 :(得分:3)

您已选择主键为PRIMARY KEY (key, column1, column2, column3, column4, column5),因此如果您要在第5列上给出where子句,则should also need to specify the where clause of key, column1, column2, column3, column4。例如,

SELECT * FROM playerInfo WHERE KEY = 'Kitty' AND column1 = 1411 AND column2 = 3 AND column3 = 713 AND column4 = 4 AND column5 = 'American';

如果您打算在第2列上给出where子句,那么您should also need to specify the where clause of key, column1。例如,

SELECT * FROM playerInfo WHERE KEY = 'Kitty' AND column1 = 1411 AND column2 = 3;

如果要在特定主键列上指定where子句,则还需要给出前一列的where子句。因此,您需要以棘手的方式选择cassandra数据建模,以获得良好的读写性能并满足您的业务需求。但是,如果业务逻辑满足您,那么cassandra性能将无法满足您。如果cassandra性能满足您,那么您的业务逻辑将无法满足您。这就是卡桑德拉的美丽。肯定的cassandra需要更多改进。

答案 1 :(得分:3)

有一种方法可以通过创建二级索引,根据不属于主键的列来选择行。 让我用一个例子解释一下。

在此架构中:

CREATE TABLE playerInfo (
    player_id int,
    name varchar,
    country varchar,
    age int,
    performance int,
    PRIMARY KEY ((player_id, name), country)
);

主键的第一部分,即player_id和name是分区键。这个哈希值将决定该行将写入cassandra集群中的哪个节点。

因此我们需要在where子句中指定这两个值来获取记录。例如

SELECT * FROM playerinfo WHERE player_id = 1000 and name = 'Mark B';

 player_id | name   | country | age | performance
-----------+--------+---------+-----+-------------
      1000 | Mark B |     USA |  26 |           8

如果主键的第二部分包含多于2列,则必须为其键的左侧的所有列指定值,包括该列。

在这个例子中

PRIMARY KEY ((key, column1), column2, column3, column4, column5)

对于基于column3的过滤,您必须指定"key, column1, column2 and column3"的值。 对于基于column5的过滤,您需要对"key, column1, column2, column3, column4, and column5"的值进行分类。

但是,如果您的应用程序要求对不属于分区键的特定列使用过滤,则可以在这些列上创建二级索引

要在列上创建索引,请使用以下命令

CREATE INDEX player_age on playerinfo (age) ;

现在您可以根据年龄过滤列。

SELECT * FROM playerinfo where age = 26;

 player_id | name    | country | age | performance
-----------+---------+---------+-----+-------------
      2000 | Sarah L |      UK |  26 |          24
      1000 |  Mark B |     USA |  26 |           8

在Cassandra中使用索引要非常小心。仅当表中的记录很少或者在这些列中具有更少的不同值时才使用此选项。

您也可以使用

删除索引
DROP INDEX player_age ;

有关详细信息,请参阅http://wiki.apache.org/cassandra/SecondaryIndexeshttp://www.datastax.com/docs/1.1/ddl/indexes