听起来你已经了解了分区键,那我会补充一下:你的分区键帮助Cassandra确定在集群中存储你的数据的令牌范围(哪个令牌范围)。每个节点负责几个主要令牌范围(假设使用vnodes)。当你的数据被写入到数据分区时,它会按照聚簇键进行排序。这也是它存储在磁盘上的方式,因此请记住你的聚簇键决定了你的数据存储顺序。
根据你的宽行结构,你可能会有比2亿行更少的限制。此外,这只是存储限制。即使你在单个分区中成功存储了100万个CQL行,查询该分区也会返回大量数据,导致查询效率低下,可能会超时。
我的大部分查询将是以下内容:
select lastest timestamp of know deviceid and tagid
Select decvalue of known deviceid and tagid and timestamp
Select alphavalue of known deviceid and tagid and timestamp
select * of know deviceid and tagid with time range
select * of known deviceid with time range
您当前的数据模型可以支持除最后一个查询之外的所有查询。为了在timestamp
上执行范围查询,您需要将数据复制到一个新表中,并构建一个支持该查询模式的PRIMARY KEY。这被称为“基于查询的建模”。我会像这样构建一个查询表:CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
PRIMARY KEY (deviceid,timestamp));
那张表可以支持以timestamp
为条件的范围查询,并且在deviceid
上分区。
但我看到这两种模型中最大的问题是"行增长不受限制"。基本上,随着您收集越来越多的设备值,您将接近每个分区的20亿个单元格限制(而且很可能在此之前就会变得非常缓慢)。你需要做的是使用一种称为“时间分桶”的建模技术。
以本例说明,我确定按月份分桶会使我保持在2亿单元格限制以下,并且允许我所需的日期范围灵活性。如果是这样,我将添加一个额外的分区键 monthbucket
,我的(新)表将如下所示:
CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
monthbucket text,
PRIMARY KEY ((deviceid,monthbucket),timestamp));
现在,当我想要查询特定设备和日期范围内的数据时,我还会指定monthbucket
:
SELECT * FROM newdata_by_deviceid_and_time
WHERE deviceid='AA23' AND monthbucket='201603'
AND timestamp >= '2016-03-01 00:00:00-0500'
AND timestamp < '2016-03-16 00:00:00-0500';
请记住,monthbucket
仅为示例。 对于您来说,使用季度甚至年可能更有意义(假设您在一年内不会存储太多值 deviceid
)。
PRIMARY KEY (monthbucket, timestamp)
。 - undefined