我在查询 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);
最佳答案
为了回答您的问题,让我们重点关注您对该表的主键的选择:
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 存储引擎不提供除主键中列出的列顺序之外的多列排序。
关于cassandra - 主键相关的CQL3查询排序时的情况和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25776438/