背景
我有一个由大约 2000 个传感器组成的网络,每个传感器都有大约 100 个数据点,我们每隔 10 分钟收集一次。这些数据点通常是 int 值,但有些是字符串和浮点数。这些数据应该存储 90 天,如果可能的话,更多并且仍然有效。
数据库设计
当最初负责这个项目时,我编写了一个 C# 应用程序,为每个传感器编写逗号分隔的文件。当时没有那么多,当有人想查看趋势时,我们会在 Excel 中打开 csv 并根据需要绘制图表。
事情发展了,我们切换到了 MySQL 数据库。我为每个传感器创建了一个表格(是的,我知道,很多表格!);它运行良好,但有一些限制。有这么多表,显然不可能编写一个查询,在查找特定值时会在所有传感器中查找数据。
对于下一个版本,我切换到 Microsoft SQL Server Express,并将所有传感器数据放入一个大表中。这也有效,并让我们进行查询以在所有感兴趣的传感器中查找值。但是,我遇到了 Express 版本的 10GB 限制,并决定切换回 MySQL 而不是投资 SQL Server Standard。
问题
我对 MySQL 的性能和可扩展性很满意,但我不确定坚持所有数据在一个表中的方法是否最好。单个表中的 10GB 似乎要求不同的设计。我应该提到的是,仍然需要查询数据以绘制图形,而且我担心绘制图形的查询会出现性能问题,例如,一个传感器在整个 90 天内的温度数据。(换句话说,图形应该是快速生成的,而无需等待 SQL 对成堆的数据进行排序以隔离感兴趣的传感器。)
我应该以某种方式拆分此表以提高性能吗?或者有这么大的桌子也不是什么稀奇事?
我在 Sensor ID 和 Timestamp 列上有索引,这几乎是任何查询的定义边界。(即从时间 A 到时间 B 获取传感器 X 的数据)。
我已经阅读了一些关于分片和分区的内容,但在这种情况下不觉得这些是合适的。
编辑:
根据到目前为止的评论和答案,一些额外的信息可能会有所帮助:
非无限期存储:目前我不存储超过 90 天的数据。每天,我都会运行一个查询来删除超过 90 天的数据。如果将来它变得重要,我会存储更多,但现在已经足够了。这有助于控制大小和高性能(呃)。
引擎类型:最初的 MySQL 实现使用了 MyISAM。这次为新实现(一个数据表而不是多个)创建表时,他们默认为 InnoDB。我不相信我对其中一个有要求。
归一化:当然还有除了数据采集表之外的其他表。这些支持表存储诸如传感器的网络信息、用户的登录信息等内容。没有太多需要规范化的内容(据我所知)。数据表有这么多列的原因是每个传感器有这么多变量。(多个温度、光照水平、气压等)对我来说标准化意味着没有冗余数据或重复组。(至少对于 1NF。)对于给定的传感器,在特定时间存储所有值需要一行数据,并且那里不涉及 1:N 关系(我看到)。 …
我在 Ubuntu 服务器上运行 MySQL 5.6.14 并注意到错误日志不断填充:
到 db 的连接 17201 中止:'somedb' 用户:'sdb' 主机:'xxxx'(读取通信数据包超时)
(这些情况每分钟大约发生 10 次。在服务器正常运行时间仅 24 小时后,计数器最多可达 13,000。)
我们可能有二十或三十个 Windows 客户端程序实例,它们通过连接器/NET (6.2.2.0) 使用 .NET 框架连接到数据库,并且我确保每次它创建连接时 (MySqlConnection.Open( )) 它也被正确关闭 (MySqlConnection.Close())。
我max_allowed_packet
根据网络研究调整了各种超时、和其他设置,但这些似乎仍然存在。
以下是(我认为是)相关设置:
connect_timeout = 20
wait_timeout = 60
net_read_timeout = 60
net_write_timeout = 60
max_allowed_packet = 33554432 // 32M
Run Code Online (Sandbox Code Playgroud)
我能做些什么来阻止这些事件不断发生?
数据库、Oracle 和 MySQL 中的定义者和调用者权限是什么?我只是不明白。