【问题标题】:DB design for sensor data (lots and LOTS of data)传感器数据的数据库设计(大量数据)
【发布时间】:2015-12-08 04:32:35
【问题描述】:

我正在编写一个用于查看和管理传感器数据的应用程序。我可以拥有无​​限数量的传感器,每个传感器每分钟读取一次并将值记录为 (时间、值、传感器 ID、位置 ID、[一堆其他双精度值])。

例如,我可能有 1000 个传感器,每分钟为每个传感器收集数据,一年后最终生成 525,600,000 行。多个用户(最多 20 个)可以绘制任何时间段的数据,在任何范围内放大和缩小,并一次为传感器的数据添加注释。用户还可以修改某些数据点,我需要跟踪原始数据和修改过的数据。

我不确定这样的应用程序的数据库应该是什么样子!它应该只是一张 SensorData 表,带有时间、sensor_id 和 location_id 的索引吗?我应该根据 sensor_id 对这个表进行分区吗?我应该每天将每个传感器的数据保存在文件中(比如 .csv 文件)并根据要求将它们加载到临时表中吗?我应该如何管理注释?

我还没有决定使用 DBMS(可能是 MySQL 或 PostgreSQL)。但我的目的是深入了解此类应用程序中的数据管理。

【问题讨论】:

  • 您是正确的,时间、传感器 ID 和位置 ID 是可能索引的列。只有您可以告诉我们哪一列是最重要的。当我从事地震勘探工作时,时间是最重要的专栏。位置 ID 仅用于校正距离的时间。您需要告诉我们哪些列是最重要的选择列。
  • 当前的关系数据库可以容纳数万亿和数万亿行。现代关系数据库不再关心行数。
  • 传感器的位置是否随时间变化?
  • 新的传感器读取数据需要多久对用户可见?它是接近实时的,还是每小时的,还是每天的......?
  • 您是否期望数据检索应该优化为读取特定传感器的所有读数,或特定时间片的所有读数?

标签: database database-design large-data


【解决方案1】:

我假设用户无法更改您显示的字段(时间、值、sensor_id、location_id),但隐含的其他字段。

在这种情况下,我建议使用版本范式。您命名的字段是静态的,也就是说,一旦输入,它们就永远不会改变。但是,许多用户可以更改其他字段。

您没有说明用户是看到所有用户的更改还是只看到他们自己的更改。我将假设所有用户都可以看到所有更改。如果该假设错误,您应该能够进行适当的更改。

首先,让我们解释一下版本范式。如您所见,它只是第二范式的一个特例。

获取您已命名的字段的元组,重新排列以将键值组合在一起:

R1( sensor_id(k), time(k), location_id, value )

如您所见,location_id(假设传感器是可移动的)和值取决于生成值的传感器和进行测量的时间。这个元组在 2nf 中。

现在您要添加可更新字段:

R2( sensor_id(k), time(k), location_id, value, user_id, date_updated, ... )

但可更新字段(包含在省略号中)不仅取决于原始关键字段,还取决于 user_id 和 date_updated。元组不再在 2nf 中。

所以我们不将新字段添加到原始元组中,而是创建一个规范化的元组:

R1( sensor_id(k), time(k), location_id, value )
Rv( sensor_id(k), time(k), user_id(k), date_updated(k), ... )

这使得每个原始阅读都有一系列任意数量的版本成为可能。

查询特定读数的最新更新:

select  R1.sensor_id, R1.time, R1.location_id, R1.value, R2.user_id, R2.date_updated, R2.[...]
from    R1
left join Rv as R2
    on  R2.sensor_id = R1.sensor_id
    and R2.time = R1.time
    and R2.date_updated =(
        select max( date_update )
        from    Rv
        where   sensor_id = R2.sensor_id
            and time = R2.time )
where   R1.sensor_id = :ThisSensor
    and R1.time = :ThisTime;

要查询特定用户的特定阅读的最新更新,只需将 user_id 值添加到主查询和子查询的过滤条件中即可。应该很容易了解如何获取特定阅读的所有更新或仅获取特定用户所做的更新。

这种设计在访问数据方面非常灵活,而且由于关键字段也被索引,因此即使在非常大的表上也非常快。

【讨论】:

  • 谢谢,是的,所有用户都可以查看所有更改。你直接去了注释。所以你认为关系数据库是解决这个问题的正确方法吗?... 2 年后,我将拥有一个包含 1 万亿行的表!我开始基于以下考虑创建数据库......如果您认为这些假设是可以的,请告诉我:我将创建一个归档策略,将两年前的所有内容推送到归档表(每天)。我将根据 sensor_id 对我的表进行分区。我会有关于时间、位置和 sensor_id 的索引。
  • 我不是 DBA,所以无法就分区等问题向您提供建议。但是,归档策略是一个好主意。您需要平衡您想要“在线”的数据量与您和您的用户需要轻松访问多远的距离。用户可以完美地处理这样的想法,即如果需要数据,例如两年以上的数据,他们只需要使用不同的屏幕。
【解决方案2】:

寻找答案我遇到了这个帖子。虽然它与我的情况并不完全相同,但它回答了我的许多问题;例如使用关系数据库是一种合理的方式(答案是“是”),以及如何处理分区、维护、归档等。

https://dba.stackexchange.com/questions/13882/database-redesign-opportunity-what-table-design-to-use-for-this-sensor-data-col

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 2017-05-24
    • 2015-04-04
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多