为什么我不能在过滤主键后在Cassandra中添加WHERE子句?

Pie*_*per 3 cassandra nosql datastax

编辑*感谢代码格式化的陌生人,我会记住以后!

我遵循基本的planetcassandra.org Cassandra教程,我不明白为什么我不能执行以下查询:

select * 
from users 
where lastname = 'Smith' AND city = 'X';
Run Code Online (Sandbox Code Playgroud)

在这张桌子上:

CREATE TABLE users 
(
    firstname text,
    lastname text,
    age int,
    email text,
    city text,
    PRIMARY KEY (lastname)
);
Run Code Online (Sandbox Code Playgroud)

根据我的理解,分区键(lastname)对数据进行分区.所以带有姓氏史密斯的所有行都应该在节点X上.什么阻止我进一步过滤这些行呢?

谢谢!

nic*_*ley 6

这里有两个问题的答案.一个特定于你的例子,一个更一般的答案(这可能是你真正想要的).

回答你的例子

在您的特定示例中,您有一个主键"lastname".因此,在这种情况下,每个分区只有一行.每当您使用姓氏"Smith"更新行时,您将覆盖该行中的所有先前数据.在这种情况下,where子句实际上没有意义,因为当您查询"Smith"行时,只会有一个结果.

更一般的答案

我猜你的意思是你的例子允许每个分区多行.也许类似于PRIMARY KEY(lastname,user_id)(或者聚类键中的任何列,可以让您识别具有相同姓氏的不同用户).

在Cassandra中,分区可能非常大.单个分区中可能有数百万行.主键中的群集列确定存储在磁盘上时这些行的排序方式.因此,当您对聚类列进行查询时,Cassandra可以使用数据排序的知识来精确查找您要查找的数据.

如果Cassandra允许查询不在群集密钥中的列,则需要扫描分区中的所有数据并根据查询检查每一行.这将是非常低效的.

要进一步扩展群集列,群集列的实际顺序也很重要.如上所述,排序确定行存储在磁盘上的方式.所以"PRIMARY KEY(a,b,c)"和"PRIMARY KEY(a,c,b)" 一样.在第一个示例中,行首先通过"b"列在磁盘上排序,然后"b"列的所有具有相同值的行按"c"列排序.这意味着您无法在分区内查询具有"c"特定值的列,而不指定"b".该查询将再次需要扫描整个分区,因为行首先按"b"排序.

了解您要预先做的确切查询将帮助您确定所需的群集密钥,以及是否需要对多个表进行非规范化以支持多个查询.