MySQL - 复合主键还是创建单独的表?

MySQL - composite primary key or create separate tables?

所以我们在现场有多个相同的设备每秒记录天气数据。然后,这个带有时间戳的数据会在远程服务器上聚合。我的目标是将这个带时间戳的数据存储在远程服务器上的 MySQL 数据库中。

假设我们有 N 台设备 - 这意味着我们有 N rows/data 行相同的时间戳。每个设备都有一个唯一的ID。

我在争论:

  1. 一个 table 以 (timestamp,device_id) 作为主键

  2. 使用时间戳作为主键

    为每个设备创建单独的table

有更好的解决方案吗?有第三种方法吗?

我们将按时间序列访问数据。

选项 #1 毫无疑问:一个 table 以 (timestamp,device_id) 作为主键。

管理多个 table,每个设备一个,很快就会变成一场噩梦。起初这似乎是个好主意,但您需要为每个数据存储或检索使用大量动态 SQL;这需要大量的实施工作,以及调试和确保质量的大量工作。如果您没有很多资源(人员)来测试它,那么它是一个不稳定的解决方案。

另一方面,MySQL 的引擎非常擅长为同一 table 中的不同设备存储和检索数据。要提高性能,只需设置正确的索引,查询应该 运行 好。持久性将很容易快速实现,并且您将避免很多简单的错误。更不用说您需要跨所有设备获取统计信息的情况,而不仅仅是单个设备。这很容易用一个 table; 解决;有多个,那将是一场噩梦。

一个table!不要设计您的数据库,因此您必须为每个设备创建一个新的 table。

为什么是 table?它将透明地处理任意数量的设备。正确索引后,它将在规模上表现得相当好。

为什么要避免每台设备 table?表使用稀缺的操作系统资源,如文件描述符和 RAM。另外,将 tables 添加到生产中的现有数据库很麻烦,尤其是如果您必须记住将新数据库与旧数据库建立索引时。

您提出的复合主键的建议是正确的。

您还应该考虑添加一个 (device_id, timestamp) 复合索引,以防您需要在单个设备上 运行 时间序列操作。

您在设计查询时阅读 覆盖索引 是明智的。

如果您以时间序列的形式访问数据,您可能会遇到很多需要对所有设备进行聚合的情况。比如记录的最高值是多少,记录的平均值是多少等

如果您将每个设备的结果存储在单独的 table 中,那么进行这些聚合会变得更加困难。您必须联合所有 table,并且每次添加具有自己的新 table 的设备时,您都必须更改代码以将新的 table 包含在联盟。

而如果您将所有数据保存在一个 table 中,使用复合键,您可以将设备 ID 视为一个属性,然后在不更改代码的情况下对任意数量的设备进行聚合。

每当我看到数据库设计中提到的“per”这个词时,我都会将其视为危险信号,很可能它表示有问题。

例如“每个测量设备一个 table”“每个月销售结果一列”。