我在cassandra日期表中有一个主键为id的数据表
SELECT * FROM Op_History ORDER BY create_time DESC limit 100;
我试过这个,但得到错误如下:InvalidRequest: 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.
主键是id
所以对于Cassandra,你需要设计你的表来支持一个特定的查询。当主键为id
时,它真正支持的唯一查询是id
的每一行。
CREATE TABLE op_history (
id UUID,
create_time TIMESTAMP,
day_bucket INT,
op_data TEXT,
PRIMARY KEY ((day_bucket),create_time,id))
WITH CLUSTERING ORDER BY (create_time DESC, id ASC);
通过在day_bucket
上进行分区,我确保特定日期的所有数据都存储在一起。我不确定op_history
背后的商业案例,但如果您需要查询整个月的数据,那么您将使用month_bucket
之类的东西来代替。
现在,我可以过滤特定日期的行:
> SELECT * FROM op_history WHERE day_bucket=20221221;
day_bucket | create_time | id | op_data
------------+---------------------------------+--------------------------------------+---------
20221221 | 2022-12-21 14:42:58.552000+0000 | 59b0a30b-213b-4847-bd3e-134a641be21f | Hello4!
20221221 | 2022-12-21 14:42:56.057000+0000 | 7148d5b3-77d7-4088-8c6d-f2e4c73175f2 | Hello3!
20221221 | 2022-12-21 14:42:53.866000+0000 | b23f4556-2a72-4014-a6e9-7a2ceb55217c | Hello2!
20221221 | 2022-12-21 14:42:47.738000+0000 | 51d09afa-806e-4bec-b6bf-94eb1a67910d | Hello!
(4 rows)
定义了CLUSTERING ORDER
后,我不需要ORDER BY
子句。
因为我没有机会改变表的创建
哦,我不是建议那样。我建议您创建一个具有不同主键定义的新表,并将相同的数据加载到其中。这实际上是Cassandra数据建模的最佳实践。
有没有可能…允许过滤
所以使用ALLOW FILTERING
指令通常被认为是"不良做法",因为它消耗了太多的资源。如果查询必须与太多节点通信,则可能会超时,甚至使协调器节点崩溃。此外,ALLOW FILTERING
仍然不允许ORDER BY
应用于它。
很多团队最终做的一件事是构建一个Spark集群来处理Cassandra数据。Spark可以从Cassandra中提取数据,并在RAM中对其执行符合ansi标准的SQL操作。这将允许您应用ORDER BY
.
另一方面,您可以尝试ALLOW FILTERING
,然后在应用程序端执行排序。绝对不理想。