概述
我想确定 cassandra 中财务即时报价数据的正确架构。
数据和架构
我有以下 csv 示例数据:
SYMBOL,DATE,TIME,PRICE,SIZE
A,2011-01-03,9:28:00,41.46,200
A,2011-01-03,9:28:00,41.46,100
A,2011-01-03,9:30:00,41.56,1300
A,2011-01-03,9:30:00,41.56,1300
A,2011-01-03,9:30:00,41.55,100
A,2011-01-03,9:30:19,41.55,200
A,2011-01-03,9:30:23,41.5169,100
A,2011-01-03,9:30:29,41.44,66534
A,2011-01-03,9:30:29,41.45,225
A,2011-01-03,9:30:30,41.44,100
A,2011-01-03,9:30:30,41.43,100
A,2011-01-03,9:30:30,41.49,100
A,2011-01-03,9:30:30,41.45,200
我存储到下表中:
CREATE TABLE tickdata (
symbol text,
date date,
time time,
price float,
size int,
PRIMARY KEY ((symbol,date),time)
);
这是表格SELECT
的一部分:
symbol | date | time | price | size
--------+------------+--------------------+---------+-------
A | 2011-01-03 | 09:28:00.000000000 | 41.46 | 100
A | 2011-01-03 | 09:30:00.000000000 | 41.56 | 1300
A | 2011-01-03 | 09:30:19.000000000 | 41.55 | 200
A | 2011-01-03 | 09:30:23.000000000 | 41.5169 | 100
A | 2011-01-03 | 09:30:29.000000000 | 41.45 | 66534
用例
数据将被写入Cassandra一次,并且大部分是在date
和symbol
条件下读取的,例如给定时间段的一组符号。
问题
元组
(symbol,date,time)
不是一个合适的PRIMARY KEY
,因为我的粒度限制在秒。因此,例如,由于键中的重复,COPY FROM
在导入过程中会删除csv的第二行。如何保存记录?假设
PRIMARY KEY
是唯一的,如何避免存储SYMBOL
和DATE
的重复值?还是分区在引擎盖下照顾这个问题?我正在考虑使用以下架构:
CREATE TABLE tickdata ( symbol text, date date, time blob, price blob, size blob, PRIMARY KEY ((symbol,date)) );
以存储原始数据。这是解决上述几点的正确方法吗?
当我
SELECT
数据时,数据不是根据PRIMARY KEY
的定义排序的。这与上面提到的非唯一性问题有关吗?我应该坚持使用我的二进制文件存储,它保留符号和日期的地图并根据要求加载相关文件吗?这样可以避免每行重复符号和日期,并且对时间戳的有限粒度(重复)无动于衷。
组(符号,日期,时间)不是正确的主键,因为我 粒度限制为秒。因此,复制自例如删除 导入期间 CSV 的第二行,由于 钥匙。如何保存记录?
第一个表定义中的主键是((symbol,date),time)
NOT(symbol,date,time)
。两者在卡桑德拉中是不同的。
((symbol,date),time)
=> 将在一个节点中存储相同符号 (A) 和日期的所有记录。对于相同的符号 (A),但其他日期可能会在其他节点上。 行键将是符号+日期
物理数据布局(示例)
|A_2011-01-03||time1.price & time1.value||time2.price & time2.value|
|A_2011-01-04||time1.price & time1.value||time2.price & time2.value|
|B_2011-01-03||time1.price & time1.value||time2.price & time2.value|
|B_2011-01-04||time1.price & time1.value||time2.price & time2.value|
(symbol,date,time)
=> 同一交易品种的所有记录将驻留在一个节点上。这可能会导致行宽。 行键将是符号。
物理数据布局(示例)
|A||date1.time1.price & date1.time1.value||date1.time2.price & date1.time2.value||date2.time1.price & date2.time1.value||date2.time2.price & date2.time2.value|
|B||date1.time1.price & date1.time1.value||date1.time2.price & date1.time2.value||date2.time1.price & date2.time1.value||date2.time2.price & date2.time2.value|
为避免删除记录,您可以再添加一列,例如uuid
或timeuuid
CREATE TABLE tickdata (
symbol text,
date date,
time time,
price float,
size int,
id timeuuid
PRIMARY KEY ((symbol,date),time,id)
);
假设主键是唯一的,我怎样才能避免存储重复的 符号和日期的值?还是分区正在解决这个问题 引擎盖下?
基于上面解释的物理存储结构,这个问题已经得到解决。
您正在谈论的备用模式将只有一个符号和一个日期的 1 条记录。您必须在应用程序端处理 blob...我认为这可能是开销。
数据不是根据主键的定义排序的 当我选择它时。这与非唯一性问题有关吗 上面说的是什么?
默认情况下,数据按聚类键的升序排序(在您的情况下)。尽管您可以通过将表的聚类顺序按属性更改为降序来更改顺序。
例:
CREATE TABLE tickdata (
symbol text,
date date,
time time,
price float,
size int,
id timeuuid
PRIMARY KEY ((symbol,date),time,id)
) WITH CLUSTERING ORDER BY(time desc,id desc);
我应该坚持使用我的二进制文件存储,它保留了符号映射吗 并根据要求确定日期并加载相关文件?这避免了 每行重复符号和日期,对有限无动于衷 时间戳的粒度(重复)。
您可以自行决定:)