4

我正在规划一个 MySql 数据库的结构,并且可以使用更多经验丰富的专业人士的一些建议。DB所属站点为每个注册用户收集90天的天气数据,必须支持数百万用户。

我已经为用户准备了一个表格,其中包含他们的登录名和联系信息,但假设我需要第二个表格来存储所有天气数据......

我打算做的基本上是为每个用户存储平均温度、湿度、风向等,每天第四次。并且每天数据库都会更新新一天的数据,同时保留昨天的条目(但仅限于 89 天的旧数据 + 当天的数据) - 适用于所有用户。

现在,拥有一个为每个用户(拥有数百万用户)包含 90 行的巨大“数据”表是否最有意义?还是出于性能原因或类似原因,是否有更聪明的方法可以做到这一点?

每次用户登录并查看他自己的个人资料或浏览其他人的个人资料时,都会访问(阅读和显示等)90 天的数据。但它每天只会更新一次(覆盖最旧的条目,保持每个用户 90 行的限制。)

4

5 回答 5

2

编辑:刚才看到每个用户都有不同的天气数据。在答案中保留“共享数据”,但您对第二种情况感兴趣。

用户共享天气数据

例如,基于他们最近的气象站 ID。

我会存储一个 (userId, stationId, isActive, isPreferred) 表来了解用户对哪些数据感兴趣,然后我会针对 stationWeatherData 运行查询以获取该站的 90 行天气数据。

每个用户都有自己的天气数据

处理 9 亿用户应该没有什么特别的问题。如果你真的需要,你可以根据 userId 在不同的表上“分片”,例如,表 weather174 将保存 (userId % 1000) 给出 174 的所有用户的数据,你会发现自己有 1000 个表 - 可能在不同的服务器 - 大小的千分之一。

因此,您从一张大表开始,并准备分片(或迁移到云存储和非 SQL 密钥库数据库,例如 MongoDB、VoltDB)。或者一旦用户 ID 达到一百万,就根据用户 ID 进行分区。

甚至,您根本不使用数据库。如果您需要搜索或关联/加入数据,那么数据库是有意义的——在这里您只是在访问用户的“气象站”。

如果您知道您永远不会查询“有多少用户的湿度为 60%?”,而始终只查询“用户 1234567 有哪些数据?”,那么您可以将数据以二进制、JSON 或 JSON 格式保存在滚动缓冲区中HTML 格式(在云存储、S3 或 MongoDB 上 - 现在每个用户只有一个文档)。很大程度上将取决于要更新的​​数据是如何到达的,即来自集中器的一大批数据或每个用户上传自己的数据。

于 2012-07-09T06:19:16.737 回答
1

我推荐一个单独的天气数据表,按日期分区(请参阅MySQL 文档关于范围分区)。

这样,您可以轻松摆脱旧数据(只需删除最旧的分区),并且查询天数范围(例如,过去 7 天的平均温度)将非常有效。

于 2012-07-09T06:26:13.813 回答
1

如果您要存储每个用户的位置,则根据位置存储天气数据并按需将其映射到用户会更简单。

UserId --> LocationId --> 天气详细信息。

假设平均而言,每个位置都会有多个用户,这应该会大大减少您的数据库大小,并且应该可以更好地扩展。

于 2012-07-09T06:15:21.163 回答
1

对于我的回答(如下),我假设数据是特定于用户的,例如来自他们个人的后院气象站。如果是与其他用户共享的数据,那么我的答案是次优的。


这似乎是合理的,但为什么要停在 90 天呢?只要他们是有效用户,就保留每个用户的日常信息。所描述的查询总是类似于

SELECT temperature_avg, humidity, wind_direction, wind_speed
FROM weather_summary
WHERE user_id = (current_user)
ORDER BY sample_date DESC
LIMIT 90;

只要 和 上有索引sample_dateuser_id这将非常有效。

根据我的经验,为每个用户设置一个单独的表格从来都不是很好。

于 2012-07-09T06:13:18.420 回答
0
  1. 在表列上创建索引(id、全文索引)。
  2. 作为一个想法,您可以在此表上创建一些视图,这些视图将包含基于位置、天、周、月或季度或字母或其他标准的过滤数据,并基于此您的代码将决定使用哪个视图来获取搜索结果。
  3. 或者,如果您的表有很多插入/更新操作,您可以创建多个表,并根据某些标准选择表名以使用您的服务器端编程语言更新/插入数据。
于 2012-07-09T06:20:49.620 回答