【问题标题】:Sum one table and update other with result, or just do `sum` on select?对一个表求和并用结果更新另一个表,或者只是在选择时执行“求和”?
【发布时间】:2020-07-11 11:10:28
【问题描述】:

可能是一个愚蠢的问题,但我正在创建一个系统,其中不允许用户在他们可以上传的图片中超过 X 安装的 kb。

上传图片时,我使用图片大小(KB)和其他信息更新images 表。

现在,我还应该跟踪users 表上每个用户图像的总大小吗?还是每次我想检查限制时我都应该只做一个select sum(size) from images where user = xxx?每次新上传都可能发生什么?

从关系的角度来看,最好的方法是什么?

【问题讨论】:

  • 除非它导致性能问题,否则您应该进行查询。否则,您必须确保在上传和删除文件时始终更新总大小列。

标签: mysql sql relational-database denormalization


【解决方案1】:

将 SUM 存储在 users 表中是一种非规范化。

如果您需要经常查询总和,这可能是值得的,而且每次需要时都进行聚合查询太慢。

但您接受users 表中存储的总和将与关联图像的真实SUM(size) 不同步的风险。

您不会认为这很困难,但在实践中,有很多边缘情况存储的总和无法更新。您最终将定期在后台运行聚合查询,以覆盖存储的总和,以防万一它不同步。

作为编码人员,非规范化更适合您,因为您必须编写代码来纠正此类异常。对于您创建的非规范化案例的数量要保守,因为每一个案例都要求您做更多的工作。

但是,如果您的求和查询比运行聚合查询更快地返回结果非常重要,那么这就是您必须做的。

根据我的经验,所有优化都是有代价的。

【讨论】:

    【解决方案2】:

    你可以使用任何一种方法。

    但是,由于您有一个与大小总和相关的业务规则,我可能会建议您使用触发器来维护用户级别的总和。尽管这对inserts/updates/deletes 有一些额外的开销,但在返回有关用户的信息时它的开销要少得多。

    这还有其他一些优点:

    • 您可以对尺寸施加业务规则。例如,您可以将大小四舍五入到最接近的 1k,然后将它们相加。您不希望这样的业务逻辑通过多个查询传播。
    • 您可以直接在users 表中实现检查约束(当然,您可以在最新版本的 MySQL 中执行此操作)。
    • 您可以索引总图像大小,以便轻松查看谁最接近其限制。

    【讨论】:

      猜你喜欢
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2021-03-29
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多