我是Cassandra的新手,并且不清楚存储我的数据以支持我的查询需求的最佳方式。我希望能够根据任一键或两者来搜索我的数据。为了说明,我将使用此表示例:
CREATE TABLE temperature (
weatherstation_id text,
event_time timestamp,
temperature text,
PRIMARY KEY (weatherstation_id,event_time)
);
这适用于像这两样的查询:
SELECT event_time,temperature FROM temperature WHERE weatherstation_id=’1234ABCD’;
...因为它直接进入单个分区
SELECT temperature FROM temperature WHERE weatherstation_id=’1234ABCD’ AND event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;
...因为它仍然会进入单个分区并从有序列表中获得一片结果
但是如果我想这样的话会怎么样:
SELECT temperature FROM temperature WHERE event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;
如果我的理解对我有用,那么这不会有效率,因为它需要迭代每个分区吗?不仅如此,它还需要按时间顺序恢复。
最好的解决方案是什么?
答案 0 :(得分:3)
其实你的查询:
SELECT temperature FROM temperature WHERE event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;
将无法运行。 Cassandra确实必须知道哪个分区必须查找您请求的数据,即您始终必须指定分区键。
为了有效地检索此查询的数据,您还需要围绕该查询建模数据:
CREATE TABLE temperature_by_time (
granularity timestamp,
event_time timestamp,
weatherstation_id text,
temperature text,
PRIMARY KEY (granularity, event_time)
);
我在这里添加了字段granularity
。此字段允许您控制分区的宽度。一个好的经验法则是每个分区最多有大约10k-100k行。根据您写入此表的速度,您可以采用不同的方式进行操作。例子:
在这种情况下,你将写出10个/秒,36k /小时的措施。一个好的粒度值就像yyyy-mm-dd HH:00:00
,就是你每小时对数据进行分区:
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:05:01', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:19:15', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:39:35', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:59:49', ...);
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00';
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00' AND event_time >= '2017-01-1 10:30:00' AND event_time < '2017-01-1 11:00:00';
即您将event_time
“截断”为整数小时,并且只能以小时/小时为单位获取记录。
在这种情况下,你将每秒写100个测量值,每小时360k测量值。然后,良好的粒度值类似于yyyy-mm-dd HH:00:00
,yyyy-mm-dd HH:15:00
,yyyy-mm-dd HH:30:00
,yyyy-mm-dd HH:45:00
,即您将数据分为四小时:
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:05:01', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:15:00', '2017-01-11 10:19:15', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:30:00', '2017-01-11 10:39:35', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:45:00', '2017-01-11 10:59:49', ...);
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00';
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00' AND event_time >= '2017-01-1 10:30:00' AND event_time < '2017-01-1 10:33:00';
即你将event_time
“截断”到四分之一小时,并且只能在一个小时内获得记录。
你已经知道如何继续......
答案 1 :(得分:2)
PRIMARY KEY ((day_of_year), event_time, weatherstation_id)
会让你有能力在一天内完成一系列时间。如果期限跨越多天,则按day_of_year
进行查询,并将其合并到应用程序中。
然后需要按时间顺序取回
不,它不会在你的例子中,因为它会返回按时间排序的行,一次一个分区。但是使用上面列出的主键,它会按时间列出它们,与weatherstation_id无关。