通常,对于这样的结构化数据集,我怀疑您可以编写一种自定义数据格式,该格式对于大多数日常操作而言速度更快(即,从任意时间提取少量数据)。迁移到标准数据库工具中可能会带来一些好处,例如临时查询,多路访问,复制,可用性等。雇用维护基于标准的数据存储的帮助也更加容易。
如果要求我建立一个数据库来存储该数据,我将执行以下操作:
拟议方案
(1)核心数据被放入许多(1000个)单独的表中,每个表包含两列:
- 时间:SQL DATETIME数据类型或某个时期的数字类型(这是主键)
- 值:根据您的数据键入适当的值。我将默认使用单精度浮点数,但是定点数据类型可能更适合金融交易。这可能是未索引的。
这些表将变得非常大,您可能需要按(例如)年份进行手动分区。但是您必须检查系统性能并进行适当调整。
这些表需要唯一的名称,并且有两个选项。它们可以是人类可读的(例如nyse_goog_dailyhighs_2010),也可以是(我偏爱的)随机的。无论哪种方式,都需要一组元数据表,并且随机表名称会阻止开发人员将任何内容推断为不应该被推断的名称。
(2)根据应用程序的要求,元数据存储在单独的表中:
需要一个附加表或一组表来跟踪元数据。这些表将包含有关交换,工具,值,频率,日期范围,出处(数据来自何处)以及您需要的其他任何数据。这些映射到数据表名称。
如果有足够的数据,则此查找实际上可以提供表名和数据库名,从而允许某种自我实现的数据分片(如果这是该术语的正确用法)。但是我会保留这一点。
然后在应用程序层,我将查询元数据表以确定我的数据位于何处,然后对大数据表执行相对简单的查询以获取我的数据。
好处:
我的经验(相对有限)是,与处理少量大表相比,数据库通常可以更轻松地处理大量小表。这种方法还可以简化维护工作(例如,清除旧数据,重建损坏的表,从备份创建/重新加载,添加新实体)。如果(例如)您拥有不同速率的数据,或者需要不同的数据类型,那么这将完全解耦不同类型的数据。
这种瘦表的概念还应该允许对最常见的查询(即来自单个实体的连续数据范围)进行快速磁盘访问。大多数数据应用程序都受磁盘I / O限制,因此值得考虑。正如评论员所暗示的那样,这对于面向列的数据库来说是理想的应用程序,但是我还没有找到一种面向主流的列产品,足以让我押注自己的职业。这种模式非常接近。
缺点:
注意事项:
变化:
我考虑过的一些变化是:
数据折叠: 如果时间序列的间隔相等,则使用一个时间戳列和(例如)10个数据列。现在,时间戳是指第一个数据列的时间,并且假设其他数据列在该时间戳和下一个时间戳之间均等间隔。这样可以节省大量以前用于存储时间戳的存储,但会带来大量的查询和/或应用程序复杂性。连续范围的单个实体查询现在需要较少的磁盘访问权限。
多路复用:如果已知多个时间序列使用相同的时间序列,则如上所述使用一个时间戳和(例如)10个数据列。但是现在每一列代表一个不同的时间序列。这需要对元数据表进行更新,而不是对表和列名称的查找。存储空间减少。查询保持简单。无论范围如何,单个实体查询现在都需要更多的磁盘访问权限。
兆表: 将“多重复用”概念发挥到极致,并将所有数据放入一个表中,每列时间序列一次。对于连续范围,单个实体查询,这需要大量磁盘访问,这是维护的噩梦。例如,现在添加新实体需要在多个TB表上使用MODIFY TABLE命令。
有关此格式的更多讨论,请参见以下内容中的各种答案:
MySQL中的列过多
完全规范化的表:
可以使用一个三列表,而不是使用许多2列表,其中的列是时间,数据ID和值。现在,您的元数据表只需要查找ID值,而不是表名或列名,从而可以将更多逻辑推入SQL查询而不是应用程序层。
现在,规范化列消耗了大约2/3的存储空间,因此这将占用大量磁盘空间。
您可以将主键顺序(数据ID,时间戳)用于快速连续的单个实体查询。或者,您可以使用主键顺序(timestamp。dataid)来加快插入速度。
但是,即使考虑了这些变化之后,我的下一个开发计划还是有很多表,每个表有两个列。那,或者该方法很快就会被比我聪明的人发布:)。