主键相关的CQL3查询案例&排序时出错

时间:2014-09-10 23:01:17

标签: cassandra cql cql3 cassandra-2.0 datastax

查询Cassandra时有两个问题:

查询1

> select * from a where author='Amresh' order by tweet_id DESC;
Order by with 2ndary indexes is not supported

我学到了什么:二级索引仅用于WHERE子句而不是ORDER BY?如果是这样,那我该如何排序?

查询2

> select * from a where user_id='xamry' ORDER BY tweet_device DESC;
Order by currently only supports the ordering of columns following their
declared order in the PRIMARY KEY.

我学到了什么:ORDER BY列可能位于主键的第二位,也许?如果是这样,那么如果我需要按多列排序呢?

表:

CREATE TABLE a(
  user_id      varchar,
  tweet_id     varchar,
  tweet_device varchar,
  author       varchar,
  body         varchar,
  PRIMARY KEY(user_id,tweet_id,tweet_device)
);

INSERT INTO a (user_id, tweet_id, tweet_device, author, body)
    VALUES ('xamry', 't1', 'web', 'Amresh', 'Here is my first tweet');
INSERT INTO a (user_id, tweet_id, tweet_device, author, body)
    VALUES ('xamry', 't2', 'sms', 'Saurabh', 'Howz life Xamry');
INSERT INTO a (user_id, tweet_id, tweet_device, author, body)
    VALUES ('mevivs', 't1', 'iPad', 'Kuldeep', 'You der?');
INSERT INTO a (user_id, tweet_id, tweet_device, author, body)
    VALUES ('mevivs', 't2', 'mobile', 'Vivek', 'Yep, I suppose');

Create index user_index on a(author);

1 个答案:

答案 0 :(得分:4)

要回答您的问题,请关注您为此表选择的主键:

PRIMARY KEY(user_id,tweet_id,tweet_device)

如上所述,user_id将用作分区键,它将数据分布在群集中,但同时保留同一节点上相同用户ID的所有数据。在单个分区中,唯一行由(tweet_id, tweet_device)对标识,这些行将由tweet_id 自动排序,因为它是主键中列出的第二列。 (换句话说,PK中第一列分区键的一部分确定了分区的排序顺序。)

查询1

WHERE子句是author='Amresh'。请注意,此子句不涉及主键中列出的任何列;相反,它使用author上的二级索引进行过滤。由于WHERE子句未使用索引指定分区键列(user_id)的确切值,因此涉及扫描所有群集节点以查找可能的匹配项。当结果来自多个副本(节点)时,无法对结果进行排序,因为这需要在协调器节点上保留整个结果集,然后才能将任何结果返回给客户端。协调员无法知道真正的“第一”结果行是什么,直到它确认已收到并排序每个可能的匹配行为止。

如果您需要特定作者姓名的信息,与用户ID分开,并按推文ID排序,请考虑将数据再次存储在不同的表中。 Cassandra的数据设计理念是以读取时所需的格式存储数据,并在必要时实际反规范化(存储冗余信息)。这是因为在Cassandra中,写入是便宜的(尽管它会给应用程序开发人员管理相同逻辑数据的多个副本的负担)。

查询2

这里,WHERE子句是user_id = 'xamry',它恰好是此表的分区键。好消息是,这将直接转到持有此分区的副本,而不是打扰询问其他节点。但是,你不能ORDER BY tweet_device,因为我在这个答案的顶部解释了。 Cassandra存储按单个列排序的行(在单个分区内),通常是主键中的第二列。在您的情况下,您可以访问user_id = 'xamry' ORDER BY tweet_id但未按tweet_device排序的数据。答案,如果您确实需要按设备排序的数据,则与查询1相同:将其存储在表中,其中该表是主键中的第二列。

如果在按user_id查找推文时,您只需按设备排序,只需翻转主键中最后两列的顺序即可。如果您需要能够对任一方式进行排序,请将数据存储在两个不同的表中两次。

除了主键中列出的列顺序外,Cassandra存储引擎不提供多列排序。