我是 No SQL 的新手,刚开始学习 Cassandra,我有以下问题要问。我创建了一个包含一列的简单表来了解 Cassandra 分区和聚类,并尝试在插入后查询所有值。
我的表结构
create table if not exists music_library(custno int, primary key(custno))
Run Code Online (Sandbox Code Playgroud)
我按顺序插入了以下值
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)
Run Code Online (Sandbox Code Playgroud)
然后我在查询这个表
select * from music_library
Run Code Online (Sandbox Code Playgroud)
它按以下顺序返回值
13
11
14
12
Run Code Online (Sandbox Code Playgroud)
但我期待
11
12
13
14
Run Code Online (Sandbox Code Playgroud)
为什么它的行为如此?
我运行了您的确切语句并产生了相同的结果。但我也调整了您的查询以运行该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)
Run Code Online (Sandbox Code Playgroud)
为什么它的行为如此?
简单地说,因为 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);
Run Code Online (Sandbox Code Playgroud)
插入一些数据后,以下查询返回按以下排序的结果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)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为我通过分区 ( album)查询数据,然后我在custno利用磁盘排序顺序进行“聚类” 。这也是数据写入磁盘的顺序,因此 Cassandra 只是按顺序从分区中读取它。
几年前我为 DataStax 写了一篇关于这个主题的文章,它仍然非常相关。如果有机会,请阅读:https : //www.datastax.com/dev/blog/we-shall-have-order