Cassandra:如果在没有受EQ或IN限制的PRIMARY KEY的情况下使用'ORDER BY'?

问题描述 投票:1回答:2

我在Scylla(一个Cassandra兼容数据库)中有一个表定义如下:

create table s.items (time timeuuid, name text, primary key (time));

我想运行一个查询,在一定时间后获取所有项目,类似于以下内容:

select * from s.items where time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

但我被告知ORDER BY is only supported when the partition key is restricted by an EQ or an IN.为了解决这个问题,我可以制作一个类似于以下内容的表和查询:

create table s.items (yes boolean, time timeuuid, name text, primary key (yes, time));

select * from s.items where yes=true and time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

虽然这有效,但它似乎不是最好的解决方案。由于我对Scylla和CQL还不熟悉,有没有更好/更合适的方法呢?

database cassandra cql scylla
2个回答
1
投票

类似的问题已得到解答。例如:Cassandra Data modelling : Timestamp as partition keys

您需要设计一个适当的分区键,这可能是一年,具体取决于预期的数据量


1
投票

您添加一个布尔键并始终将其设置为yes的解决方案基本上会创建一个包含所有数据的巨大分区。这很少是你真正想要的。如果这一个分区是您的整个数据,则意味着即使您在每个节点上有一个10个节点的集群,每个节点上有8个CPU,集群中所有80个CPU中只有3个CPU将执行任何工作(因为每个分区属于一个某些CPU,并且RF = 3,有三个副本)。

如果你想知道为什么你的原始解决方案不起作用而且Scylla拒绝了“ORDER BY”,那么问题是,虽然Scylla可以扫描整个表格来查找时间X之后的条目(你需要添加'允许过滤'到查询',它没有有效的方法来排序它找到的时间。在内部,不同的分区不按分区键排序,而是按“分号”(分区键的散列函数)排序。具有随机化效果的散列对于平衡群集上所有CPU之间的负载很重要,但是会阻止Scylla(或Cassandra)以原始密钥顺序读取分区。

你可以做的一件事就是做Alex上面建议的,这是你的原始设置和你提出的解决方案之间的中间点:每个分区没有一个项目,或者单个分区中的所有项目,但是中:例如,想象一下,在您的工作量中,您每天都会收集100MB的数据。因此,您使用日期编号作为分区键(而不是您的bool)。一天中的所有数据都将位于一个分区中。在每天的分区内,不同的条目(行)将按聚类键顺序排序,这将是时间。使用此设置,要在特定日期之后检索所有项目,只需逐个查询每个单独的日期。例如,查询第134天,然后是第135天,它们是136,然后是等等......在每一天内,结果将被排序。所以问题解决了。

该技术是一种众所周知的“时间序列”数据建模。 Scylla(和Cassandra)甚至有一个特殊的压实策略,针对这种建模,TWCS(时间窗压缩策略)进行了调整。

© www.soinside.com 2019 - 2024. All rights reserved.