如何在sql server中存储定时数据点

时间:2014-11-20 09:11:38

标签: sql-server time-series

我需要在数据库(SQL服务器)中存储一个点列表,我不确定我选择的选项是否是最佳解决方案。

这些数据点非常基本,十进制值表示时间t的测量值,以及基本时间戳,它只是一个表示从测量开始起的秒数的int。

在我的域中,我有一个Measurement类,其中包含这些数据点的列表。

我现在拥有的是MeasurementValue

MeasurementValue
----------------
TimeStamp INT PK
MeasurementId INT PK + FOREIGN KEY on Measurement
Value DECIMAL

一次测量有大约1000个数据点,测量次数可能只有几百个,也就是数千个。

我真的不关心能够查询这个MeasurementValue表,它总是作为一个整体。

我知道包含此表的点数可能足够小,无法通过此设计进行管理,但我想知道在未来这些数字会增长的情况下是否有更好的选择

3 个答案:

答案 0 :(得分:1)

Gimly, 你有两个选择。一种是按照你的建议创建一个表。虽然你可能想稍微改变一下(虽然改变很重要);

实体 - 属性 - 值看起来像这样;

MeasurementID PK FK
TimeStamp PK
Value

一些SQL人员非常不利于EAV;但是,当它有意义时,它是有道理的。 这样可以正常工作,因为您只需在需要时返回数据。只需加入桌子并称之为好。在这种情况下,像这样的小数据类型,你将能够在页面上放置大量的行。除非始终按顺序插入measurementID行,否则我可能不会担心聚簇索引。在MeasurementID周围维护非聚集索引的堆应该没问题。

EDIT-ADDED:无论您是聚集还是非聚集,MeasurementID都需要在索引中排在第一位。原因是您希望时间戳与测量值分组,而不是按时间戳分组的测量值。 IE根据测量值选择所有时间戳,而不是根据时间戳选择所有测量值。

另一个选项也可以使用,但我建议你先测试一下,就像你建议你的数据内联在Measurement表上一样。使用XML,您可能不需要经历并生成模式文件,但它是一种保持内联关系的方法。

MeasurementID, Col1, Col2, col3, MeasurementDetailXML

并将XML列设置为 超行的大值类型= ON

http://technet.microsoft.com/en-us/library/ms189087(v=sql.105).aspx

这会将大列推出常规数据页面。只在需要时选择列。在SQL中有很多关于XML的好文章,我通常会回到这一篇; http://technet.microsoft.com/en-us/library/ms345118(v=sql.90).aspx

您的XML可能如下所示;

<MeasurementDetail>
  <TimeStamp> </TimeStamp>
  <Value> </Value>
</MeasurementDetail>
<MeasurementDetail>
  <TimeStamp> </TimeStamp>
  <Value> </Value>
</MeasurementDetail>
....

有很多方法可以形成XML文档,因此请使用您认为合适的方法。

在实践中,不要让它变得更复杂。我建议编写一个EAV表只是因为它易于开发,维护以及其他人快速获取代码的能力。

有许多正确的答案,所以请选择最简单的答案,除非您证明其不足以满足业务需求。

答案 1 :(得分:1)

一般的表格设计看起来完全正常化并且很好。小数值的范围和精度是多少?数据类型的默认大小可能大于您的要求。在http://msdn.microsoft.com/en-us/library/ms187746.aspx

在线查看图书

从技术上讲,数据库中的每一列都可以命名为“Value”。我可能会将列名更改为更能指示实际数据的内容。

我建议不要对你的价值观进行反规范化。是的,它可以加快数据检索性能(检索1个大行,而不是许多小行和所有这些索引列的开销),但是你必须解析blob,那么你实际需要多长时间保存?如上所述,使用分隔的值列表,您将丢失单个时间戳(并且您必须担心已为您分隔的十进制值留出足够的空间),如果您使用XML,为什么打扰关系数据库?

关于索引,我没有明确的答案,只有一些设计问题。

如果在查询时总是从表中检索所有数据,则索引在很大程度上是无关紧要的(主键实施除外)。但是,这意味着您希望所有测量的所有值都适用于所有实验......这似乎不太可能。

规划问题:数据的到期日期是什么时候?一旦加载,它会永远保留在那里,还是最终会从系统中删除?今天开发中的快速发展在一年后的制作中经常是可怕的。

正在批量加载数据。这些数据是按顺序排列还是按随机顺序排列?加载性能(和潜在的表锁定)是否关键或不相关?

我的下意识反应是将聚簇索引打开(MeasurementId,TimeStamp)。但是:

  • 如果MeasurementId是第一列,则对给定测量的所有值的查询(和删除)将很快
  • 仅当数据已按索引顺序排序时,批量加载到聚簇索引才有效
  • 如果未排序,或者稍后添加数据,您将获得页面拆分和碎片。如果后续修改是一个问题,则需要识别和设置适当的填充因子。
  • 批量加载期间,您可能遇到表锁定问题。如果这是一个主要问题,表分区可能值得考虑。

答案 2 :(得分:-1)

根据您的问题和评论,您可以选择以下其中一项。

首先是你的普通桌面设计。

MeasurementValue
----------------
TimeStamp datetime PK
MeasurementId int PK + FOREIGN KEY on Measurement
Value DECIMAL

如果要查询“值”列并在数据库中对其进行操作,请选择此选项。

MeasurementValue
----------------
TimeStamp datetime PK
MeasurementId int PK + FOREIGN KEY on Measurement
Value varchar(8000) comma separated int values.

如果您要查询“值”列并在数据库中对其进行操作,请选择此项。

根据您的问题,第二种设计将更好地为您提供存储和查询速度选项。 您也可以选择将测量值存储为与上次测量值的差值,而不是从开始时间戳开始测量。见下面的例子。

Measurent Values difference  from start timestamp
1,2,10,12,20
Measurent Values difference from last measurement
1,1,8,2,8

这将使您的Value列更小,以便varchar(8000)更有可能容纳您的每个值。