对一个 table 求和并用结果更新另一个,还是只对 select 求和?

Sum one table and update other with result, or just do `sum` on select?

这可能是一个虚拟问题,但我正在创建一个系统,在该系统中,用户上传的图片不能超过 X mounts kb。

上传图片时,我用图片大小(以 KB 为单位)和其他信息更新 images table。

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

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

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

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

这还有其他一些优点:

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

将 SUM 存储在 users table 中是一种反规范化。

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

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

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

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

但是,如果您查询总和 return 的结果比 运行 聚合查询更快,那么这就是您必须要做的。

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