【问题标题】:Should I store 90 rows of data for EVERY user (with millions of users)?我应该为每个用户(数百万用户)存储 90 行数据吗?
【发布时间】:2012-07-09 06:07:04
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 天气数据是特定于用户的(他们有专门测量数据的设备?还是像城市数据,一个城市有 50000 个用户?因此不同的数据是相同的)用户?

标签: mysql database


【解决方案1】:

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

用户分享天气数据

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

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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


    这似乎是合理的,但为什么要停在 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 上有索引,这将非常高效。

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

    【讨论】:

    • 感谢您的回答!关于您的问题:我一直在考虑 90 天的限制,只是为了限制数据库的大小,因为它将拥有数百万用户。
    • @user805220:不要担心会有数百万用户。一百或一千的合理模式与十亿相同。一旦你有了一个可靠的设计,扩展它就很简单了:分布式、分区等。存储成本几乎是免费的。高效访问它需要一点小心,但并不难掌握。
    【解决方案3】:

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

    UserId --> LocationId --> 天气详情。

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

    【讨论】:

    • 不是每个位置(例如城市),而是每个用户。
    【解决方案4】:

    我建议为天气数据使用一个表,按日期分区(请参阅MySQL documentation on range partitioning)。

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

    【讨论】:

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

      【讨论】:

        猜你喜欢
        • 2021-04-17
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        • 2019-09-15
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        相关资源
        最近更新 更多