首页 > 解决方案 > Cassandra 返回数值的无序结果集

问题描述

我是 No SQL 的新手,刚开始学习 Cassandra,我有一个问题要问。我创建了一个包含一列的简单表来了解 Cassandra 分区和集群,并尝试在插入后查询所有值。

我的表结构

create table if not exists music_library(custno int,  primary key(custno))

我按顺序插入了以下值

insert into music_library(custno) values (11) 
insert into music_library(custno) values (12) 
insert into music_library(custno) values (13) 
insert into music_library(custno) values (14) 

然后我在查询这张表

select * from music_library

它按以下顺序返回值

13
11
14
12

但我期待

11
12
13
14

为什么它的行为如此?

标签: cassandra

解决方案


我运行了您的确切陈述并产生了相同的结果。但是我还调整了您的查询以运行该token函数,这就是它产生的结果:

aaron@cqlsh:stackoverflow> select custno,token(custno) from music_library;

 custno | system.token(custno)
--------+----------------------
     13 | -5034495173465742853
     11 | -4156302194539278891
     14 |  4279681877540623768
     12 |  8582886034424406875

(4 rows)

为什么它的行为如此?

简单地说,因为 Cassandra 无法按分区键的值对结果进行排序。

由于您的表有一个主键custno,因此您的行由 的哈希标记值分区custno,并写入负责这些标记范围的节点。当您在 Cassandra 中运行未绑定查询(不带WHERE子句的查询)时,返回的结果按其分区键的哈希标记值排序。

在这里使用ORDER BY也行不通。 ORDER BY只能对分区内的数据进行排序,即使这样也只能对集群键进行排序。要使custno值正确排序,您需要找到一个新的分区键,然后custno按升序指定为集群键。

编辑 20190916 - 后续澄清

所有列都会发生这种标记化吗?

不会。分区键被散列到一个令牌中以确定它们在集群中的位置(它们被写入哪个节点)。单个列值写入分区内

我将如何将插入的号码与订单一起退回?

您不能在不更改模型的情况下更改此表的顺序。简而言之,您必须找到一种方法将您期望返回的值(与您的查询一起)组织在一起(找到另一个分区键)。具体外观取决于您的业务/查询要求。

例如,假设我想跟踪哪些客户购买了特定的音乐专辑。我可能会创建一个如下所示的表:

CREATE TABLE customers_by_album (
  album TEXT,
  band TEXT,
  custno INT,
  PRIMARY KEY (album,custno))
WITH CLUSTERING ORDER BY (custno ASC);

插入一些数据后,以下查询返回按 排序的结果custno

aaron@cqlsh:stackoverflow> SELECT album,token(album),band,custno FROM
    customers_by_album WHERE album='Moving Pictures';

 album           | system.token(album) | band | custno
-----------------+---------------------+------+--------
 Moving Pictures | 7819329704333693835 | Rush |     11
 Moving Pictures | 7819329704333693835 | Rush |     12
 Moving Pictures | 7819329704333693835 | Rush |     13
 Moving Pictures | 7819329704333693835 | Rush |     14

(4 rows)

这是可行的,因为我通过分区 ( album) 查询数据,然后我正在“集群”上custno利用磁盘排序顺序。这也是数据写入磁盘的顺序,因此 Cassandra 只是按顺序从分区中读取数据。

几年前我为 DataStax 写了一篇关于这个主题的文章,它仍然非常相关。如果有机会,请阅读:https ://www.datastax.com/dev/blog/we-shall-have-order


推荐阅读