MongoDB数据建模小案例:物联网时序数据库建模

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

注:本案例来自MongoDB官方教程PPT,也是一个非常典型的CASE,故此翻译,并结合当前MongoDB版本做了一些内容上的更新。

本案例非常适合与IoT场景的数据采集,结合MongoDB的Sharding能力,文档数据结构等优点,可以非常好的解决物联网使用场景。

需求

案例背景是来自真实的业务,美国州际公路的流量统计。数据库需要提供的能力:

  • 存储事件数据
  • 提供分析查询能力
  • 理想的平衡点:

    • 内存使用
    • 写入性能
    • 读取分析性能
  • 可以部署在常见的硬件平台上

几种建模方式

每个事件用一个独立的文档存储

{
    segId: "I80_mile23",
    speed: 63,
    ts: ISODate("2013-10-16T22:07:38.000-0500")
}
AI 代码解读
  • 非常“传统”的设计思路,每个事件都会写入一条同样的信息。多少的信息,就有多少条数据,数据量增长非常快。
  • 数据采集操作全部是Insert语句;

每分钟的信息用一个独立的文档存储(存储平均值)

{
    segId: "I80_mile23",
    speed_num: 18,
    speed_sum: 1134,
    ts: ISODate("2013-10-16T22:07:00.000-0500")
}
AI 代码解读
  • 对每分钟的平均速度计算非常友好(speed_sum/speed_num);
  • 数据采集操作基本是Update语句;
  • 数据精度降为一分钟;

每分钟的信息用一个独立的文档存储(秒级记录)

{
    segId: "I80_mile23",
    speed: {0:63, 1:58, ... , 58:66, 59:64},
    ts: ISODate("2013-10-16T22:07:00.000-0500")
}
AI 代码解读
  • 每秒的数据都存储在一个文档中;
  • 数据采集操作基本是Update语句;

每小时的信息用一个独立的文档存储(秒级记录)

{
    segId: "I80_mile23",
    speed: {0:63, 1:58, ... , 3598:54, 3599:55},
    ts: ISODate("2013-10-16T22:00:00.000-0500")
}
AI 代码解读

相比上面的方案更进一步,从分钟到小时:

  • 每小时的数据都存储在一个文档中;
  • 数据采集操作基本是Update语句;
  • 更新最后一个时间点(第3599秒),需要3599次迭代(虽然是在同一个文档中)

进一步优化下:

{
    segId: "I80_mile23",
    speed: {
        0:  {0:47, ..., 59:45},
        ...,
        59: {0:65, ... , 59:56}
    }
    ts: ISODate("2013-10-16T22:00:00.000-0500")
}
AI 代码解读
  • 用了嵌套的手法把秒级别的数据存储在小时数据里;
  • 数据采集操作基本是Update语句;
  • 更新最后一个时间点(第3599秒),需要59+59次迭代;

嵌套结构正是MongoDB的魅力所在,稍动脑筋把一维拆成二维,大幅度减少了迭代次数;

每个事件用一个独立的文档存储VS每分钟的信息用一个独立的文档存储

从写入上看:后者每次修改的数据量要小很多,并且在WiredTiger引擎下,同一个文档的修改一定时间窗口下是可以在内存中合并的;
从读取上看:查询一个小时的数据,前者需要返回3600个文档,而后者只需要返回60个文档,效率上的差异显而易见;
从索引上看:同样,因为稳定数量的大幅度减少,索引尺寸也是同比例降低的,并且segId,ts这样的冗余数据也会减少冗余。容量的降低意味着内存命中率的上升,也就是性能的提高;

每小时的信息用一个独立的文档存储VS每分钟的信息用一个独立的文档存储

从写入上看:因为WiredTiger是每分钟进行一次刷盘,所以每小时一个文档的方案,在这一个小时内要被反复的load到PageCache中,再刷盘;所以,综合来看后者相对更合理;
从读取上看:前者的数据信息量较大,正常的业务请求未必需要这么多的数据,有很大一部分是浪费的;
从索引上看:前者的索引更小,内存利用率更高;

总结

那么到底选择哪个方案更合理呢?从理论分析上可以看出,不管是小时存储,还是分钟存储,都是利用了MongoDB的信息聚合的能力。

  • 每小时的信息用一个独立的文档存储:设计上较极端,优势劣势都很明显;
  • 每分钟的信息用一个独立的文档存储:设计上较平衡,不会与业务期望偏差较大;

落实到现实的业务上,哪种是最优的?最好的解决方案就是根据自己的业务情况进行性能测试,以上的分析只是“理论”基础,给出“实践”的方向,但千万不可以此论断。

VS InfluxDB

说到时序存储需求,大家一定还会想到非常厉害的InfluxDB,InfluxDB针对时序数据做了很多特定的优化,但MongoDB采用聚合设计模式同样也可以大幅度较少数据尺寸。根据最新的测试报告,读取性能基本相当,压缩能力上InfluxDB领先MongoDB。但MongoDB的优势在于可以存储更丰富的信息,比如地理坐标,文本描述等等其他属性,业务场景上支持更广泛。
另外,MongoDB的Sharding水平扩展能力,Aggragation功能,Spark Connector等等特性,对IoT来说,生态优势明显。

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
打赏
0
0
0
3
9250
分享
相关文章
数据库数据恢复——sql server数据库被加密的数据恢复案例
SQL server数据库数据故障: SQL server数据库被加密,无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密,文件名字被篡改。
分布式存储数据恢复—hbase和hive数据库数据恢复案例
分布式存储数据恢复环境: 16台某品牌R730xd服务器节点,每台服务器节点上有数台虚拟机。 虚拟机上部署Hbase和Hive数据库。 分布式存储故障: 数据库底层文件被误删除,数据库不能使用。要求恢复hbase和hive数据库。
58 12
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
数据库数据恢复——MongoDB数据库服务无法启动的数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 管理员在未关闭MongoDB服务的情况下拷贝数据库文件。将MongoDB数据库文件拷贝到其他分区后,对MongoDB数据库所在原分区进行了格式化操作。格式化完成后将数据库文件拷回原分区,并重新启动MongoDB服务。发现服务无法启动并报错。
服务器数据恢复—云服务器上mysql数据库数据恢复案例
某ECS网站服务器,linux操作系统+mysql数据库。mysql数据库采用innodb作为默认存储引擎。 在执行数据库版本更新测试时,操作人员误误将在本来应该在测试库执行的sql脚本在生产库上执行,导致生产库上部分表被truncate,还有部分表中少量数据被delete。
105 25
数据库数据恢复—SQL Server报错“错误 823”的数据恢复案例
SQL Server数据库附加数据库过程中比较常见的报错是“错误 823”,附加数据库失败。 如果数据库有备份则只需还原备份即可。但是如果没有备份,备份时间太久,或者其他原因导致备份不可用,那么就需要通过专业手段对数据库进行数据恢复。
数据库数据恢复——MySQL简介和数据恢复案例
MySQL数据库数据恢复环境&故障: 本地服务器,安装的windows server操作系统。 操作系统上部署MySQL单实例,引擎类型为innodb,表空间类型为独立表空间。该MySQL数据库没有备份,未开启binlog。 人为误操作,在用Delete命令删除数据时未添加where子句进行筛选导致全表数据被删除,删除后未对该表进行任何操作。
数据库数据恢复—MongoDB数据库迁移过程中丢失文件的数据恢复案例
某单位一台MongoDB数据库由于业务需求进行了数据迁移,数据库迁移后提示:“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”
mongoDB导出数据库所有集合内容到json文件
网上搜了一圈,官方并有提供批量导出所有集合到json文件的方法。有不少脚本可以实现,但是我还是习惯用java,如下 package starcLL.
2254 0
微服务——MongoDB常用命令1——数据库操作
本节介绍了 MongoDB 中数据库的选择、创建与删除操作。使用 `use 数据库名称` 可选择或创建数据库,若数据库不存在则自动创建。通过 `show dbs` 或 `show databases` 查看所有可访问的数据库,用 `db` 命令查看当前数据库。注意,集合仅在插入数据后才会真正创建。数据库命名需遵循 UTF-8 格式,避免特殊字符,长度不超过 64 字节,且部分名称如 `admin`、`local` 和 `config` 为系统保留。删除数据库可通过 `db.dropDatabase()` 实现,主要用于移除已持久化的数据库。
78 0

相关产品

  • 云原生多模数据库 Lindorm
  • 云数据库 MongoDB 版
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等