我以原始形式(csv和二进制文件)累积了大量数据 - 每天4GB,准确几个月。
我决定加入文明世界并使用数据库来访问数据,我想知道什么是正确的布局;格式非常简单:每次勾选几次(出价,询价,时间戳等)x高达0.5万亿/天x数百种金融工具x数据。
有一个带有MYISAM的MySQL服务器(我知道这种用法是正确的引擎)在商用硬件上运行(2 x 1GB RAID 0 SATA,核心2 @ 2.7GHz)
数据库的布局是什么?表/索引应该如何?这种情况的一般建议是什么?您预测会给我带来哪些陷阱?
编辑:我的常见用法是提取特定日期和工具的时间序列信息的简单查询,例如
SELECT (ask + bid) / 2
WHERE instrument='GOOG'
AND date = '01-06-2008'
ORDER BY timeStamp;
编辑:我试图将所有数据填入一个由timeStamp索引的表中但速度太慢 - 因此我认为它需要更复杂的方案。
答案 0 :(得分:7)
你并没有真正说出你的背景是什么以及你对编程和database design了解多少。听起来你应该做一些阅读。从概念上讲,您的设计相当简单。您的描述只标识了两个实体:
所以你需要确定属性。
金融工具:
引用:
对金融工具的提及就是所谓的foreign key。每个表还需要一个primary key,可能只是一个自动增量字段。
概念上相当简单。
CREATE TABLE instrument (
id BIGINT NOT NULL AUTO_INCREMENT,
code CHAR(4),
company_name VARCHAR(100),
PRIMARY KEY (id)
);
CREATE TABLE quote (
id BIGINT NOT NULL AUTO_INCREMENT,
intrument_id BIGINT NOT NULL,
dt DATETIME NOT NULL,
bid NUMERIC(8,3),
ask NUMERIC(8,3),
PRIMARY KEY (id)
)
CREATE INDEX instrument_idx1 ON instrument (code);
CREATE INDEX quote_idx1 ON quote (instrument_id, dt);
SELECT (bid + ask) / 2
FROM instrument i
JOIN quote q ON i.id = q.instrument_id
WHERE i.code = 'GOOG'
AND q.dt >= '01-06-2008' AND q.dt < '02-06-2008'
如果您的数据集足够大,您可能希望在表格中包含(bid + ask)/ 2,这样您就不必动态计算。
好的,这就是标准化视图。在此之后,您可能需要开始进行性能优化。考虑一下这个关于storing billions of rows in MySQL的问题。分区是MySQL 5.1+的一个特性(相当新)。
但另一个要问自己的问题是:你需要存储所有这些数据吗?我问这个的原因是我曾经在网上经纪工作,我们只存储了一个非常有限的窗口的所有交易,交易将是一个比报价更小的数据集,你似乎想要。
存储数十亿行数据是一个严重的问题,而且你真的需要认真帮助解决这个问题。
答案 1 :(得分:2)
您需要做的是阅读database normalization。如果您发现该文章太多,您应该浏览一下3rd normal form教程。
答案 2 :(得分:2)
当以刻度级别存储数据时,许多财务数据库至少通过工具对数据进行分区,因为很少需要跨仪器运行查询。因此每个工具的表格是正常的。有些更进一步,按日期划分,每个工具/日期组合给出一个表格。如果跨日期的查询是常态,这会使查询变得更加困难。
所以有两个选择:
这是访问速度和查询简易性之间的基本权衡。
答案 3 :(得分:1)
或者考虑一下星型模式,维度和事实。 Ralph Kimball有一些nice stuff告诉你如何去做。
答案 4 :(得分:1)
达尼, 我多年来一直在使用Tick by Tick数据,我很乐意就此进行合作。给我发电子邮件IanTebbutt在Hotmail。 (顺便说一下,我已经检查过,并且无法在StackOverflow上发送私人电子邮件,杰夫似乎反对它rejected,。)
简单地说,我发现按日期划分和仪器可以很好地工作。您可以选择使用InstrumentX_YYDD等模式将仪器X的数月数据放入一组表中。然后在访问至少需要一个表名生成器的数据时,更可能是一个sql生成器,它可以决定使用哪个单表,或者可能使用Union查看多个表。
无论您如何看待这种数据量都不容易处理。这接近数据仓库领域,并且有很多方法可以为那只猫设置皮肤。就像我说的那样,很乐意合作 - 我可能已经解决了一半的问题。
答案 5 :(得分:0)
只是一些一般意见:
TIMESTAMP
列,因为它会根据INSERT
时间自动设置。由于您正在导入数据,这不是您想要的。DATETIME
列类型,则可以在其上使用MySQL Date and Time functions。FOREIGN KEY
约束,并默默忽略它们。FULLTEXT
searches。INSERT
和SELECT
查询的实时数据库,请考虑将InnoDB用于事务和行级锁定(SELECT ... FOR UPDATE
)