我正在寻找一种存储与时间范围相关的数据的好方法,以便以后能够有效地检索它。
每个数据条目都可以简化为(start time, end time, value)
。我需要稍后检索属于(x, y)
范围内的所有条目。在SQL中,查询类似于
SELECT value FROM data WHERE starttime <= x AND endtime >= y
你能否为Cassandra建议一个数据结构,这样我就能有效地执行这些查询?
答案 0 :(得分:6)
有效建模这是一件非常困难的事情。
我认为使用Cassandra的二级索引(以及目前仍然需要的虚拟索引值)是您的最佳选择。每个事件需要使用一行,至少有三列:'start','end'和'dummy'。为每个创建二级索引。前两个可以是LongType,最后一个可以是BytesType。有关详细信息,请参阅this post on using secondary indexes。因为你必须在至少一个列上使用EQ表达式来进行二级索引查询(我提到的不幸要求),所以EQ将在'dummy'上,它总是可以设置为0.(这意味着EQ索引表达式)将匹配每一行,基本上是一个无操作。)您可以将其余的事件数据存储在开始,结束和虚拟的行中。
在{Campandra客户端的pycassa中,您的查询将如下所示:
from pycassa.index import *
start_time = 12312312000
end_time = 12312312300
start_exp = create_index_expression('start', start_time, GT)
end_exp = create_index_expression('end', end_time, LT)
dummy_exp = create_index_expression('dummy', 0, EQ)
clause = create_index_clause([start_exp, end_exp, dummy_exp], count=1000)
for result in entries.get_indexed_slices(clause):
# do stuff with result
其他客户应该有类似的东西。
我首先考虑的替代方案是OrderPreservingPartitioner,它几乎总是一件坏事。对于索引,您可以使用开始时间作为行键,将结束时间用作列名称。然后,您可以使用start_key = start_time和column_finish = finish_time执行范围切片。这将在开始时间之后扫描每一行,并仅在finish_time之前返回具有列的行。效率不高,你必须做一个大的多重等等。内置的二级索引方法更好,因为节点只会索引本地数据,并且大多数样板索引代码都是为你处理的。