我正在设计物联网/远程信息处理 Web 应用程序,并且正在寻找最佳的数据库架构。
我的要求:
- 数据库应该处理大约 100,000 个设备,每个设备每 30 秒传输一次数据。这意味着系统每秒需要处理大约 3,333 次插入操作。
- 平均行长约300字节
- 数据应该可用 1 年,导致总共大约 1050 亿行。
- 超过一年的数据应压缩/存档(仅用于备份)并从主数据库中删除。
- 插入操作应该是并发的,理想情况下甚至对于同一设备也是如此。
- 理想情况下,数据库应该允许将 JSON(或 JSONB)对象存储为数据字段之一,以适应来自某些设备的额外字段,动态变化。
- 每个设备都分配给特定的客户。
- 数据应以以下方式存储:
a) 允许轻松检索每个设备或一组设备的最新传输数据。
b) 促进分析以生成报告,例如确定所有设备在过去一天的平均速度和其他复杂的聚合。
- 大多数查询将涉及所需数据的 device_id(或多个)和日期/时间范围。
- 更新操作将很少见
鉴于这些因素,
- 你会如何设计数据库层?
- 10,000 个设备的设计是否不同?
我对任何数据库类型、SQL 或 NoSQL 都持开放态度。
到目前为止我的想法:
MongoDB(带集群模式):
a) 每个客户都有自己的数据库(模式)。
b) 每个设备都有自己的集合。
c) 一些额外的集合将存储有关设备及其引用的数据。
d) 一个集合将存储所有设备的最新传输数据。
优点:
- 数据按客户划分,简化了安全性和数据管理。
- 每个设备都有自己的集合,每个集合限制为大约 100 万个文档。
- 灵活的架构 - 每个设备都可以有不同的架构。
- 很少或根本不关心数据库锁。
缺点:
- 由于集合之间的大量查找和复杂的聚合操作,生成报告和聚合具有挑战性并且可能很慢。
- 难以更新所有设备的架构(尽管这种情况很少见)。
- 100,000 个集合——不确定这是否是最佳实践。
关系数据库(如具有集群模式的 PostgreSQL/MySQL):
a) 每个客户没有单独的数据库。
b) 每个设备都有自己的带有适当索引的表。
c) 每个设备表的日期/时间范围分区。
d) 一张表存储所有设备的最新传输数据。
优点:
- 更轻松的报告/汇总和分析。
- 每个设备都有自己的表,每个表限制为大约 100 万行。
- 更熟悉 SQL 方法(个人)。
- 更容易更新架构。
缺点:
- 与 MongoDB 相比,性能可能较慢,特别是对于写操作。
- 锁的潜在问题。
我一直在考虑 TimescaleDB,这是一个 PostgreSQL 扩展,它为基于时间的数据提供了很好的特性。
另一种选择:
使用关系数据库在同一个表中的所有设备数据
- 使用每个 customer_id 和 device_id 的索引
- 基于时间范围的分区(例如每个月)