Cassandra如何按时间戳排序

Yur*_*yad 2 sorting cql cassandra cassandra-2.0 cassandra-3.0

我有桌子 -

CREATE TABLE IF NOT EXISTS Chat(
  id UUID,
  time timestamp,
  idSender UUID,
  message varchar,
  PRIMARY KEY ((id),time))
WITH CLUSTERING ORDER BY(time DESC);
Run Code Online (Sandbox Code Playgroud)

我想按时间对我的消息进行排序。但是当我运行时,Cassandra 不会对我的表进行排序:

select * from chat order by time
Run Code Online (Sandbox Code Playgroud)

它显示消息

Error from server: code=2200 [Invalid query]
message="ORDER BY is only supported when the
partition key is restricted by an EQ or an IN.
Run Code Online (Sandbox Code Playgroud)

如何按时间对表格进行排序?

Aar*_*ron 5

需要明确的是,Cassandra 使用集群键(time在您的情况下)来强制执行磁盘排序顺序。但它只能在分区键内强制执行此顺序。

所以这应该有效:

SELECT * FROM chat WHERE id = db14789e-ede0-4852-a397-d0ccc7d8349e;
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要指定ORDER BY,因为您已经在表定义中指定了。当然,除非您想翻转排序方向(升序与降序)。

如果这没有帮助,那么您需要使用不同的分区键重建表,根据该分区键对数据进行分区确实有意义。然后按该分区键的查询将返回按 排序time。但在 Cassandra 中,您不能简单地选择表中的所有行,并期望它主要按分区键的哈希标记值以外的任何内容进行排序。

我不使用它,因为 id 是唯一的

专业提示:如果您不打算通过它进行查询,那么将它用作分区键就没有意义。

需要获取最后 100 条消息

因此,最好的方法可能是使用称为“分桶”的分区技术。在这种情况下,我们可以(例如)按天创建一个存储桶,如下所示:

CREATE TABLE IF NOT EXISTS chat_by_day(
  day TEXT,
  id UUID,
  time timestamp,
  idSender UUID,
  message TEXT,
  PRIMARY KEY ((day),time,id))
WITH CLUSTERING ORDER BY(time DESC,id ASC);
Run Code Online (Sandbox Code Playgroud)

插入一些数据后,我可以按天查询,并看到按时间排序的结果:

cassdba@cqlsh:stackoverflow> SELECT time,message FROM chat_by_day
                               WHERE day='20180621' LIMIT 100;

 time                            | message
---------------------------------+--------------------------------------------------------
 2018-06-21 14:51:14.863000+0000 |                                 No...I am your father.
 2018-06-21 14:51:14.858000+0000 | If only you could see what I have seen with your eyes.
 2018-06-21 14:51:14.854000+0000 |                                         Game over man!
 2018-06-21 14:50:13.369000+0000 |                                 There can be only one.

(4 rows)
Run Code Online (Sandbox Code Playgroud)

现在这只是一个例子,但希望它能为您指明正确的方向。

奇怪的是不能按时间排序

嗯,这是一个设计考虑因素,可以追溯到 Cassandra 的构建方式。分布式数据库可能仍然在一个节点上拥有所有副本(如 Neo4j),但分片数据库(根据定义)则不然。在大型系统中,您肯定不想要“热”节点(一个节点比另一个节点拥有更多数据),因此构建它以一种有利于均匀分布的方式对数据进行重新排序更有意义。考虑到这一点,就更容易理解为什么整体数据顺序/排序很快成为次要考虑因素。