我目前正在考虑改变内部时间序列的存储空间.它们都包含来自许多不同来源的财务数据.目前,我们将数据存储在专有数据库中.这是非常Nosql,它有自己的查询语言.
我对社区输入感兴趣:如何将数据存储在sql数据库中?在Nosql上使用sql有什么优点,特别是对于时间序列?考虑将其存储在sql中,我是疯了吗?
我们的数据集包含数百万个时间序列,其中大约10%包含数百万条记录.
时间序列按层次组织:/市场/工具/价值/频率,其中:
>市场是一种证券交易所等,基本上是一种仪器的集合,通常是类似的工具.
>仪器是一种仪器.这可能是一个指标(布伦特原油),股票(GOOG)等
>值是仪器的多种数据类型之一.这可能是接近,高,低等
>频率是特定时间序列值的频率.每周,每日,每月,勾选,任意等
如何将数据存储在sql数据库中?一个大表(可能由某些东西划分),每个市场或工具一个表,每个时间系列一个表.
先感谢您.
解决方法
如果我被要求设置数据库来存储该数据,我会执行以下操作:
提议的架构
(1)核心数据被放入多个(1000个)单独的表中,每个表包含两列:
> time:sql DATETIME数据类型或某个时代的数字类型(这是主键)
> value:根据您的数据输入.我会默认使用单精度浮点数,但定点数据类型可能更适合金融交易.这可能是没有索引的.
这些表会变得非常大,您可能希望按(例如)年份手动对它们进行分区.但您必须检查系统性能并根据需要进行调整.
这些表需要唯一的名称,并且有几个选项.它们可以是人类可读的(例如nyse_goog_dailyhighs_2010)或(我的偏好)随机.无论哪种方式都需要一组元数据表,并且随机表名称可以防止开发人员在名称中推断出任何不想推断的内容.
(2)根据应用程序的要求,元数据存储在单独的表中:
需要一个额外的表或一组表来跟踪元数据.这些表格将包含有关交换,工具,价值,频率,日期范围,出处(数据来自何处)以及您需要的任何其他内容的数据.它们映射到数据表名称.
如果有足够的数据,这个查找实际上可以提供一个表名和数据库名,允许一种自我实现的数据分片(如果这是对该术语的正确使用).但我会保留这一点.
然后在应用程序层,我将查询元数据表以确定我的数据所在的位置,然后对大数据表执行相对简单的查询以获取我的数据.
好处:
>我的(相对有限的)经验是数据库通常比较少数量的大表更容易处理大量的小表.此方法还可以更轻松地进行维护(例如,清除旧数据,重建损坏的表,从备份创建/重新加载,添加新实体).如果(例如)您拥有不同速率的数据或需要不同的数据类型,则会完全解耦不同类型的数据.
>这个瘦的表概念还应该允许快速磁盘访问我怀疑是最常见的查询,来自单个实体的连续数据范围.大多数数据应用程序都受磁盘I / O限制,因此值得考虑.正如一位评论者所暗示的那样,这对于面向列的数据库来说是一个理想的应用程序,但我还没有找到一个主流的列产品,足以让我打赌我的职业生涯.这个架构非常接近.
缺点:
>大约一半的磁盘空间专用于存储时间戳,当坦率地说,100或1000的表将在时间戳列中具有完全相同的数据. (实际上,如果要执行简单的表连接,这是一个要求).
>存储表名并执行动态查找需要大量的应用程序复杂性和字符串操作,这让我感到畏缩.但它似乎仍然比替代品更好(下面讨论).
注意事项:
>小心在你的时间领域进行四舍五入.您希望您的值足够圆,以启用连接(如果适用),但精确到足以明确.
>小心时区和夏令时.这些很难测试.我会在数据存储上强制执行UTC要求(这可能会让我不受欢迎)并处理应用程序中的转换.
变化:
我考虑过的一些变化是:
数据折叠:如果时间序列间隔相等,则使用一个时间戳列和(例如)10个数据列.时间戳现在指的是第一个数据列的时间,并且假设其他数据列在该时间戳和下一个时间戳之间等间隔.这节省了大量先前用于存储时间戳的存储,但代价是显着的查询和/或应用程序复杂性.连续范围的单实体查询现在需要较少的磁盘访问.
多路复用:如果已知多个时间序列使用相同的时间序列,则使用一个时间戳和(例如)10个数据列,如上所述.但现在每列代表不同的时间序列.这需要更新元数据表,而不是查找表和列名.存储空间减少.查询仍然很简单.无论连续范围如何,单实体查询现在需要更多的磁盘访问.
Mega-table:将“多路复用”概念发挥到极致,并将所有数据放入一个表中,每列一次.这需要对连续范围,单个实体查询进行大量磁盘访问,这是一个维护噩梦.例如,添加新实体现在需要在许多TB表上使用MODIFY TABLE命令.
有关此格式的其他讨论,请参阅以下各种答案:
@L_301_0@
完全标准化的表格:
您可以使用一列三列表,而不是使用许多2列表,其中列是time,dataid和value.现在,您的元数据表只需要查找ID值,而不是表名或列名,这样可以将更多逻辑推送到SQL查询中,而不是应用程序层.
现在大约有2/3的存储空间与规范化列一起使用,因此这会占用大量磁盘空间.
您可以使用(dataid,timestamp)的主键顺序进行快速连续的单实体查询.或者,您可以使用(timestamp.dataid)的主键顺序来加快插入速度.
然而,即使在考虑了这些变化之后,我对下一个开发的计划就是大量的表格,每个表格都有两列.那个,或者很快就会被一个比我更聪明的人发布的方法:).