我需要在数据库(SQL服务器)中存储一个点列表,我不确定我选择的选项是否是最佳解决方案。
这些数据点非常基本,十进制值表示时间t的测量值,以及基本时间戳,它只是一个表示从测量开始起的秒数的int。
在我的域中,我有一个Measurement
类,其中包含这些数据点的列表。
我现在拥有的是MeasurementValue
表
MeasurementValue
----------------
TimeStamp INT PK
MeasurementId INT PK + FOREIGN KEY on Measurement
Value DECIMAL
一次测量有大约1000个数据点,测量次数可能只有几百个,也就是数千个。
我真的不关心能够查询这个MeasurementValue
表,它总是作为一个整体。
我知道包含此表的点数可能足够小,无法通过此设计进行管理,但我想知道在未来这些数字会增长的情况下是否有更好的选择
答案 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)。但是:
答案 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)更有可能容纳您的每个值。