在数据库中使用可变数量的字段存储测量的最有效方法是什么?

时间:2009-10-27 08:41:17

标签: database firebird

我们有一个数据采集系统,可以从环境传感器收集测量结果,测量流经河流或河道的水流速度。每次测量都会生成固定数量的值(例如日期,时间,温度,压力等)以及速度值列表 最初传感器提供了三个速度值,因此我只是将每个值存储在FireBird数据库中单个表的自己的列中。后来传感器被引入,可以输出多达9个速度值,所以我简单地添加了6个列。尽管大多数传感器使用的值少于9个,但我认为如果大多数列仅包含零,则不会出现问题。
但是现在我面临的新一代可以输出1到256个值,我认为添加另外247列不会非常有效,特别是因为大多数测量仍然只包含3到9个值。 /> 由于每10分钟收集一次测量数据,并且数据库包含30到50个传感器的所有数据,因此数据总量在几年后非常显着,但必须能够生成任意随机时间段的概述/图表。

那么存储变量值列表的最有效方法是什么? 由于每条记录都有自己唯一的ID,我假设我可以将所有速度值存储在单独的表中,每个值都用它的记录ID标记。我只是感觉这不会非常有效,而且在一段时间之后会变得很慢。

3 个答案:

答案 0 :(得分:4)

如果使用高效索引,数据库可以处理表中的大量数据。所以你可以使用这个表结构:

create table measurements (
     id,
     seq integer, -- between 1 and 256
     ts timestamp, -- Timestamp of the measurement
     value decimal(...)
)

idid, seqts上创建索引。这将允许您有效地搜索数据。如果您不信任您的数据库,只需插入几百万行并运行几个选项以查看它的票价。

为了比较:我这里有一个拥有1.12亿行的Oracle数据库,我可以按时间戳或ID在120ms(0.12s)内选择一条记录

答案 1 :(得分:0)

您可以在文本字段中保存序列化数据,例如将测量值JSON编码为:

[<velocity-value-1>, <velocity-value-2>, ...]

然后,在您的代码中,在查询后反序列化值。

如果您只通过其他字段过滤查询,而不是按保存的值过滤,则此方法应该可以正常工作。如果您按值过滤,在WHERE子句中使用它们将是一场噩梦。

答案 2 :(得分:0)

我会选择第二张桌子:

table measurements (Id, DateTime, Temperature, Pressure)
table velocity (Id, MeasurementId, Sequence, Value)

Velocity.MeasurementId引用Measurements.Id Velocity.Sequence是该测量的速度值的索引(1-256)。

使用尽可能接近真实世界的数据填充这些表,并测试sql语句以找到最佳索引。