我是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
为什么它表现得那样?
我运行了您的确切语句并产生了相同的结果。 但是我也调整了您的查询以运行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