我希望使用apache cassandra数据库来存储~1000
符号的1分钟OHLCV财务数据的时间序列。这将需要在数据流入时实时更新。所有不需要time>24hr old
的条目应该被丢弃。
假设过去24小时内每分钟有1000个带有条目的符号,则条目总数将达1000*(60*24) = 1,440,000
。
我有兴趣设计这个数据库,以便从快速查询时间中检索过去[30m, 1h, 12h, 24h]
的所有符号的切片。最终,我需要检索总结此切片的OHLCV。对于每个符号,结果输出将是切片的{symbol, FIRST(open), MAX(high), MIN(low), LAST(close), SUM(volume)}
。这基本上总结了1m OHLCV条目,并从查询时创建[30m, 1h, 12h, 24h]
OHLCV。例如。如果我想从下午1:32检索过去的1小时OHLCV,查询将给我一个1小时的OHLCV,代表下午12:32-1-1:32的数据。
满足这些要求的好设计是什么?我并不关心数据库在硬盘上的内存占用情况。真正的问题是快速查询时间对cpu和ram的影响很小。
我想出了一种简单而天真的方式来存储每个记录,并按时间排序聚类:
CREATE TABLE symbols (
time timestamp,
symbol text,
open double,
high double,
low double,
close double,
volume double
PRIMARY KEY (time, symbol)
) WITH CLUSTERING ORDER BY (time DESC);
但我不知道如何从中选择以满足我的要求。我宁愿专门为我的查询设计它,并在必要时复制数据。
任何建议都将不胜感激。
答案 0 :(得分:1)
虽然不是基于Cassandra,Axibase Time Series Database可能与此特定用例非常相关。它支持使用时间序列语法extensions的SQL将数据聚合为任意长度的句点。
15分钟窗口的OHLCV查询可能如下所示:
SELECT date_format(datetime, 'yyyy-MM-dd HH:mm:ss', 'US/Eastern') AS time,
FIRST(t_open.value) AS open,
MAX(t_high.value) AS high,
MIN(t_low.value) AS low,
LAST(t_close.value) AS close,
SUM(t_volume.value) AS volume
FROM stock.open AS t_open
JOIN stock.high AS t_high
JOIN stock.low AS t_low
JOIN stock.close AS t_close
JOIN stock.volume AS t_volume
WHERE t_open.entity = 'ibm'
AND t_open.datetime >= '2018-03-29T14:32:00Z' AND t_open.datetime < '2018-03-29T15:32:00Z'
GROUP BY PERIOD(15 MINUTE, END_TIME)
ORDER BY datetime
请注意上面的GROUP BY PERIOD
子句,它完成了幕后的所有工作。
查询结果:
| time | open | high | low | close | volume |
|----------------------|----------|---------|----------|---------|--------|
| 2018-03-29 10:32:00 | 151.8 | 152.14 | 151.65 | 152.14 | 85188 |
| 2018-03-29 10:47:00 | 152.18 | 152.64 | 152 | 152.64 | 88065 |
| 2018-03-29 11:02:00 | 152.641 | 153.04 | 152.641 | 152.69 | 126511 |
| 2018-03-29 11:17:00 | 152.68 | 152.75 | 152.43 | 152.51 | 104068 |
您可以使用Type 4 JDBC driver,API客户端或仅curl来运行这些查询。
我使用上述示例的示例1分钟数据,您可以按照这些compression tests中的说明从Kibot下载。
此外,ATSD支持scheduled queries将更精确的数据实现到更长持续时间的OHLCV条中,例如长期保留。
免责声明:我为Axibase工作。