Database 传感器数据的数据库设计(大量数据)

Database 传感器数据的数据库设计(大量数据),database,database-design,large-data,Database,Database Design,Large Data,我正在编写一个用于查看和管理传感器数据的应用程序。我可以拥有无限数量的传感器,每个传感器每分钟读取一次数据,并将值记录为(时间、值、传感器id、位置id,[一组其他双精度]。 例如,我可能有1000个传感器,每分钟收集一个传感器的数据,一年后生成525600000行。多个用户(最多20个)可以绘制任意时间段的数据,在任意范围内放大和缩小,并一次向传感器的数据添加注释。用户还可以修改某些数据点,我需要跟踪原始数据和修改后的数据 我不确定这样的应用程序的数据库应该是什么样子!它应该只是一个表Sens

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

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

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


我还没有决定使用DBMS(可能是MySQL或PostgreSQL)。但我的目的是了解此类应用程序中的数据管理。我假设用户不能更改您显示的字段(时间、值、传感器id、位置id),而是更改其他隐含字段

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

您无法说明用户是看到了所有用户的更改还是只看到了自己的更改。我假设所有用户都能看到所有更改。如果这个假设是错误的,你应该能够做出适当的改变

首先,让我们解释一下标准形式。正如你们将看到的,这只是第二范式的一个特例

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

R1( sensor_id(k), time(k), location_id, value )
如您所见,位置_id(假设传感器可移动)和值取决于生成值的传感器和进行测量的时间。这个元组是2nf

现在要添加可更新字段:

R2( sensor_id(k), time(k), location_id, value, user_id, date_updated, ... )
但是可更新字段(包含在省略号中)不仅依赖于原始密钥字段,还依赖于用户id和更新日期。元组不再在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值添加到主查询和子查询的筛选条件中。应该很容易看到如何获取特定阅读的所有更新,或者仅获取特定用户所做的更新


这种设计在访问数据的方式上非常灵活,而且因为关键字段也被索引,所以即使在非常大的表上,它也非常快速。

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


时间、传感器id和位置id是可能要索引的列,这是正确的。只有你能告诉我们哪个栏目最重要。当我从事地震勘探工作时,时间是最重要的专栏。位置id仅用于校正距离的时间。您需要告诉我们哪些列是最重要的选择列。当前的关系数据库可以容纳数万亿行。现代关系数据库不再关注行数。传感器的位置是否会随着时间的推移而变化?新的传感器读取数据多久需要让用户可见?它是接近实时的,还是每小时的,还是每天的…?您是否希望数据检索应该优化以读取特定传感器的所有读数,或读取特定时间片的所有读数?谢谢,是的,所有用户都可以查看所有更改。你直接去了注释。所以你认为关系数据库是解决这个问题的正确方法?。。。两年后,我将拥有一张1万亿行的桌子!我开始创建数据库时考虑了以下因素。。。如果您认为这些假设是正确的,请告诉我:我将创建一个归档策略,将超过两年的所有内容推送到归档表(每天)。我会根据传感器id对我的表进行分区。我会对时间、位置和传感器id进行索引。我不是DBA,所以我不能就分区之类的问题向您提供建议。但是,归档策略是一个好主意。您需要平衡您想要“在线”的数据量与您和您的用户需要轻松访问的距离。用户可以完美地处理这样的想法:如果需要数据,比如说,超过两年的数据,他们只需要使用不同的屏幕。