如何选择我的Cassandra密钥进行正确的默认排序?
我的表格如何选择我的Cassandra密钥进行正确的默认排序?,cassandra,cql,Cassandra,Cql,我的表格samples由以下列组成: id : uuid created : timestamp device : ascii reading : float 我的大多数查询都是在所有设备上获取最新的n样本,因此我希望这是默认排序: SELECT*FROM samples LIMIT 1024 我还希望能够有效地获取给定设备的最新n样本: 从设备='abc'限制1024的示例中选择* 我应该如何设计分区键来实现这一点?对于Cassandra,建议采用基于查询的建模方法。为此,需要支持的每个
samples
由以下列组成:
id : uuid
created : timestamp
device : ascii
reading : float
我的大多数查询都是在所有设备上获取最新的n
样本,因此我希望这是默认排序:
SELECT*FROM samples LIMIT 1024
我还希望能够有效地获取给定设备的最新n
样本:
从设备='abc'限制1024的示例中选择*
我应该如何设计分区键来实现这一点?对于Cassandra,建议采用基于查询的建模方法。为此,需要支持的每个查询都有一个表是很常见的
SELECT * FROM samples LIMIT 1024
对于第一个查询,我马上看到的最大问题是没有WHERE
子句。这将导致Cassandra必须检查每个节点以构建结果集;我绝对不希望这种情况发生。但听起来你最关心的是最近的数据,或者某个特定日期的数据。为此,我们需要基于日期/时间组件创建一个分区键或“bucket”
注意,这也是必需的,因为从多个分区检索的数据无法排序。
为此,数据的基数很重要。您选择的是前1024名,那么在一天内获得这么多是常见的吗?还是超过一周?现在,我假设“day”,并添加一个day\u bucket
列
CREATE TABLE samples_by_day (
id uuid,
created timestamp,
device ascii,
reading float,
day_bucket bigint,
PRIMARY KEY (day_bucket,created,id)
) WITH CLUSTERING ORDER BY (created DESC, id ASC);
此主键定义将按天对数据进行分区(例如:20200710)。在这些分区中,数据将由创建的按降序排列(将最新的数据放在顶部)。添加了id
列以确保唯一性。这将支持以下查询:
SELECT * FROM samples_by_day
WHERE day_bucket = 20200710 LIMIT 1024;
您可以在多天内运行多个查询。您甚至可以每周或每月“存储桶”,假设这不会超过20亿个单元/分区的限制
支持此查询:
SELECT * FROM samples
WHERE device = 'abc' LIMIT 1024;
…要容易得多
这是可行的,但可能会遇到“未绑定行增长”的问题。基本上,如果继续为每个设备添加设备样本,分区大小最终将达到最大值。因此,添加day\u bucket
(或bucket适合您的任何时间)作为额外的分区键可能是必要的:
PRIMARY KEY ((device,day_bucket),created,id)
通过此更改,查询也需要更改:
SELECT * FROM samples_by_device
WHERE device = 'abc' AND day_bucket = 20200710 LIMIT 1024;
如果我想要最新的n
样本,但我不知道这是多少天,这是如何工作的?我是否需要在应用程序端实现这一逻辑,并继续要求更多的时间,直到我有足够的时间?@sdgfsdh我想说,您完全可以在应用程序级别抽象它,使它看起来像是一个调用,但在数据访问层(每天)单独调用Cassandra。
SELECT * FROM samples_by_device
WHERE device = 'abc' AND day_bucket = 20200710 LIMIT 1024;