我不在乎SQL和NoSQL之间的一般差异(或它们的传统差异)。

我目前正在研究更改内部时间序列的存储方式。它们都包含来自许多不同来源的财务数据。当前,我们将数据存储在专有数据库中。这非常类似于NoSQL,它具有自己的查询语言。

我对社区的投入很感兴趣:如何将数据存储在SQL数据库中?通过NoSQL使用SQL有什么优点,特别是对于时间序列?我为考虑将其存储在SQL中而疯狂吗?

我们的数据集包含数百万个时间序列,其中约10%包含数百万个记录。 :/ Market / Instrument / Value / Frequency,其中:市场是证券交易所等,基本上是一系列工具的集合,通常是类似的工具。
仪器是一种乐器。这可以是指标(布伦特原油),权益(GOOG)等。值是工具的多种数据类型之一。这可以是接近,高,低等。
频率是特定时间序列值的频率。每周,每天,每月,刻度,任意等。

如何将数据存储在SQL db中?一张大桌子(也许被某些东西隔开),每个市场或工具一张桌子,每个时间序列一张桌子。

谢谢您。

评论

所有时间序列是否都包含相同的元数据(即列)?

听起来像是一个数据仓库...在SO上查看此内容:stackoverflow.com/q/2684462/27535

@ jack-douglas:您是否要建议一个面向列的数据存储?

@Nicolas没想到,传统的SQL RDBMS非常适合您的数据,因为a)查询起来更容易,b)卷听起来听起来不切实际(数十亿行?)c)日期分区听起来自然而然。 /或标准OLAP功能。我问有关元数据的问题,以确定您需要多少张表。如果每个时间序列都有唯一的元数据,那么您需要数百万个表,这在常规RDBMS上听起来并不是一个好主意,但我认为您不需要吗?

@Nicolas您是否研究了SQL Server的新Hadoop连接器。从表面上看,您的方案看起来很合适。

#1 楼

通常,对于这样的结构化数据集,我怀疑您可以编写一种自定义数据格式,该格式对于大多数日常操作来说速度更快(即从任意时间提取小数据)。迁移到标准数据库工具中可能会带来一些好处,例如临时查询,多路访问,复制,可用性等。雇用维护基于标准的数据存储的帮助也更加容易。

如果要求我建立一个数据库来存储该数据,我将执行以下操作:

建议的架构

(1)核心数据被放入许多数据中(1000个)单个表,每个表包含两列:


time:SQL DATETIME数据类型或某个时期(这是主键)中的数字类型
值:根据您的数据键入适当的值。我将默认使用单精度浮点数,但是定点数据类型可能更适合金融交易。这些表可能没有索引。

这些表将变得非常大,您可能希望按(例如)年份进行手动分区。但是您必须检查系统性能并进行适当调整。

这些表需要唯一的名称,并且有两个选项。它们可以是人类可读的(例如nyse_goog_dailyhighs_2010),也可以是(我个人偏爱)随机的。无论哪种方式,都需要一组元数据表,并且随机表名可防止开发人员将任何内容推断为不应该被推断的名称。

(2)元数据存储在单独的表中,因为应用程序需要的:

还需要一个附加表或一组表来跟踪元数据。这些表将包含有关交换,工具,价值,频率,日期范围,出处(数据来自何处)以及您需要的其他任何数据。这些映射到数据表名称。

如果有足够的数据,则此查找实际上可以提供表名和数据库名,从而允许某种自我实现的数据分片(如果这是该术语的正确用法)。但是我会保留这个。

然后在应用程序层,我将查询元数据表以确定我的数据位于何处,然后对大数据表执行相对简单的查询以获取我的数据。

优点:


我的经验(相对有限)是,与处理少量大表相比,数据库通常可以更轻松地处理大量小表。这种方法还可以简化维护工作(例如清除旧数据,重建损坏的表,从备份创建/重新加载,添加新实体)。如果(例如)您拥有不同速率的数据,或者需要不同的数据类型,那么这将完全解耦不同类型的数据。
这种瘦表概念还应该允许快速磁盘访问(我怀疑这是最常见的查询) ,即来自单个实体的连续数据范围。大多数数据应用程序都受磁盘I / O限制,因此值得考虑。正如评论员所暗示的那样,这对于面向列的数据库来说是理想的应用程序,但是我还没有找到一种面向列的产品,该产品足以让我押注自己的职业。这种模式非常接近。

缺点:


大约一半的磁盘空间专用于存储时间戳,而坦率地说100或1000个表在时间戳列中将具有完全相同的数据。 (实际上,这是您要执行简单的表联接所必需的。)
存储表名并执行动态查找需要大量的应用程序复杂性和字符串操作,这让我感到有些畏缩。但是它似乎仍然比其他方法更好(如下所述)。

注意事项:


注意在时间范围内四舍五入。您希望您的值足够取整以启用联接(如果适用),但又要足够精确以使其明确。
请注意时区和夏时制。这些很难测试。我会在数据存储上执行UTC要求(这可能会使我不受欢迎)并处理应用程序中的转换。

变体:

数据折叠:如果时间序列的间隔相等,则使用一个时间戳列和(例如)10个数据列。现在,时间戳记是指第一个数据列的时间,并且假定其他数据列在该时间戳记与下一个时间戳记之间是等距的。这样可以节省大量以前用于存储时间戳的存储,但会带来大量的查询和/或应用程序复杂性。连续范围,单个实体查询现在需要较少的磁盘访问。

多路复用:如果已知多个时间序列使用同一时间序列,则使用一个时间戳和(例如)10个数据列作为如上所述。但是现在每一列代表一个不同的时间序列。这需要对元数据表进行更新,而不是对表和列名称的查找。存储空间减少。查询保持简单。不管连续的范围如何,单实体查询现在都需要更多的磁盘访问权限。每列。对于连续范围,单个实体查询,这需要大量磁盘访问,这是维护的噩梦。例如,现在添加一个新实体需要在多个TB表上使用MODIFY TABLE命令。

有关此格式的其他讨论,请参见以下答案: />
完全标准化的表:
代替使用许多2列表,您可以使用一个3列表,其中的列是时间,数据ID和值。现在,您的元数据表只需要查找ID值,而不是表名或列名,从而可以将更多逻辑推入SQL查询而不是应用程序层。

规范化列现在消耗了大约2/3的存储空间,因此这将占用大量磁盘空间。

您可以使用(dataid (时间戳),用于快速连续的单个实体查询。或者,您可以使用(timestamp。dataid)的主键顺序进行更快的插入。 。那,或者比我更聪明的人即将发布的方法:)。

评论


非常感谢您的回答。您提出了一些非常有效的观点。我完全同意存储在UTC中。我正在执行将所有数据传递到UTC的前端(Web,桌面和移动)的想法。我们有跨国客户,操作系统应该负责时间转换。我有一个DBA公司在处理我们的整个数据集,不知道其他人会提出什么。再次感谢。

–尼古拉斯(Nicolas)
11年8月8日在8:01

当DBA顾问致力于针对强大的SQL Server安装进行定位时,我将继续使用BigData安装进行测试。

–尼古拉斯(Nicolas)
11年8月8日在8:02

也许这是一个很好的解决方案,但是真正的“时间序列”应用程序应该支持“放大到数据”功能,而数据库对此无能为力。时间序列数据库更多关于聪明的“放大”和“缩小”。

–罗马·波克洛夫斯基
16-2-5在17:20

#2 楼

使用MongoDB,您可以非常快速地动态创建集合。着眼于将数据安排到单独的数据库中以及这些数据库中的集合。考虑一下需要多少内存才能将每个分片保留在系统内存中-如果您需要快速检索。坚持使用内部解决方案很愚蠢,如果有新鲜事物可以按照您的需要发展。听起来像是一个好主意。

评论


您将如何在Mongo中存储时间序列?每个文件都是一个时间序列?或特定时间戳记的值?

– RockScience
2012年3月7日在9:23

为了有效地针对非周期性甚至周期性数据执行此操作,最好预先分配数据块。每个块都是一个带有少量簿记数据的文档,一个值固定大小的数组,以及一个时间固定大小的数组。然后,您可以将系列的元数据存储在单独的文档中。在此元数据文档中,维护一个小的嵌套文档,该文档将充当数据段的簿记员,即跟踪当前数组索引和段_id。

– RYS
16年6月6日在4:53