在每天 86400 秒和每周 604800 秒时,您将每天存储 691200 行和每周 4838400 行。即使不知道您的行有多宽,在单个查询中返回也太多了。 Cassandra 非常适合存储大量这样的数据。但是像这样查询大量数据......不是那么多。
您可能希望按小时进行分区,但即使这样也会给您 28800 行。这至少是半可控的,所以让我们继续吧。
我会构建一个如下所示的表,在week 和hourBucket 上进行分区,同时在writeTime 上进行集群:
CREATE TABLE youAreAskingCassandraForTooManyRows (
week text,
hourBucket text,
writeTime timestamp,
value text,
PRIMARY KEY ((week,hourBucket),writeTime))
WITH CLUSTERING ORDER BY (writeTime DESC);
然后我可以通过分区键查询特定的星期和小时:
aploetz@cqlsh:stackoverflow> SELECT *
FROM youareaskingcassandrafortoomanyrows
WHERE week='201607-3' AND hourBucket ='20160713-14';
week | hourBucket | writetime | value
----------+--------------+--------------------------+--------
201607-3 | 20160713-14 | 2016-07-13 14:01:18+0000 | value6
201607-3 | 20160713-14 | 2016-07-13 14:01:14+0000 | value5
201607-3 | 20160713-14 | 2016-07-13 14:01:12+0000 | value4
201607-3 | 20160713-14 | 2016-07-13 14:01:10+0000 | value3
201607-3 | 20160713-14 | 2016-07-13 14:01:07+0000 | value2
201607-3 | 20160713-14 | 2016-07-13 14:01:04+0000 | value1
(6 rows)
甚至针对特定范围,基于集群键writetime。
aploetz@cqlsh:stackoverflow> SELECT *
FROM youareaskingcassandrafortoomanyrows
WHERE week='201607-3' AND hourBucket ='20160713-14'
AND writetime > '2016-07-13 14:01:05+0000'
AND writetime < '2016-07-13 14:01:18+0000';
week | hourBucket | writetime | value
----------+--------------+--------------------------+--------
201607-3 | 20160713-14 | 2016-07-13 14:01:14+0000 | value5
201607-3 | 20160713-14 | 2016-07-13 14:01:12+0000 | value4
201607-3 | 20160713-14 | 2016-07-13 14:01:10+0000 | value3
201607-3 | 20160713-14 | 2016-07-13 14:01:07+0000 | value2
(4 rows)
select * from keyspace.rootTable; -> returns all rows from all tables
不言而喻,如果我认为查询一整周超过 400 万行的数据会非常庞大以至于会超时,那么查询整个表是一个巨大的坏主意。
需要注意的是,Cassandra 不是关系数据库。它是一个分布式系统,因此运行未绑定查询(没有 WHERE 子句的查询)会在您的方程式中引入大量网络时间。这就是为什么您总是希望为所有 SELECT 查询指定至少一个分区键,因为这样您就可以保证您将从单个节点满足该查询。
您应该看看 Patrick McFadin 在Getting Started with Time Series Data Modeling 上的文章。这应该可以帮助您了解如何像这样对数据进行分区,并让您走上正确的道路。