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上.什么阻止我进一步过滤这些行呢?
谢谢!
这里有两个问题的答案.一个特定于你的例子,一个更一般的答案(这可能是你真正想要的).
回答你的例子
在您的特定示例中,您有一个主键"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"排序.
了解您要预先做的确切查询将帮助您确定所需的群集密钥,以及是否需要对多个表进行非规范化以支持多个查询.