MySQL - 动态计算字段与存储计算数据

2022-08-30 23:14:36

如果以前有人问过这个问题,我很抱歉,但我似乎找不到关于动态计算与在数据库中存储字段的问题的答案。

我读了几篇文章,建议最好在可能的情况下进行计算,但我只想知道这是否仍然适用于以下2个例子。

示例 1.假设您正在存储与汽车相关的数据。您存储的油箱尺寸以升为单位,以及每 100 公里使用多少升。您还想知道它可以行驶多少KM,这可以通过罐体尺寸和经济性来计算。我看到了2种方法:

  1. 添加或更新汽车时,计算KM的数量并将其作为静态字段存储在数据库中。
  2. 每次访问汽车时,都要计算动态的KM数量。

由于汽车经济/坦克尺寸不会改变(尽管可以对其进行编辑),因此KM是一个非常静态的值。我不明白为什么每次进入汽车时我们都会计算它。这难道不会浪费CPU时间,而不是简单地将其存储在数据库中的单独字段中,并仅在添加或更新汽车时才进行计算吗?

我的下一个例子,几乎是一个完全不同的问题(但在同一主题上),与计算儿童有关。

假设我们有一个包含类别和项目的应用程序。我们有一个视图,其中显示所有类别,以及每个类别中所有项目的计数。再一次,我想知道什么更好。要执行MySQL查询以在每次访问页面时计算每个类别中的所有项目?或者将计数存储在类别表的字段中,并在添加/删除项目时更新?

我知道存储任何可以计算的东西都是多余的,但我担心计算字段或计数记录可能会很慢,而不是将数据存储在字段中。如果不是,那么请让我知道,我只想了解何时使用任何一种方法。在小范围内,我想无论哪种方式都无关紧要,但是像Facebook这样的应用程序,它们真的会计算每次有人查看您的个人资料时您拥有的朋友数量,还是只是将其存储为字段?

我很感激对这两种方案的任何回应,以及任何可能解释计算与存储的好处的资源。

提前致谢,

基督教


答案 1

将冗余引入数据库是一种有效的优化方法。与所有优化一样,除非您确认这是瓶颈的实际位置,否则不要这样做。


答案 2

需要注意的一件事是您使用数据的方式。如果多个应用程序或应用程序的多个层(可能是同一应用程序中的旧代码和新代码)正在访问您的数据,则可以通过在数据库中进行预计算来降低计算错误的风险。然后,无论哪个应用程序请求它,您的计算数据将始终相同。

对于您的第一个示例,没有理由有一天有人必须更改您的KM的计算方式。我会将其存储在数据库中(通过触发器或通过PHP插入/更新 - 因为MySQl触发器是...好吧,他们是...不如其他一些数据库触发器好)。

现在,如果我们举第二个例子,真的不确定有人会不希望有一天在类别计算上添加一些过滤器。例如,仅以 2 到 5 岁之间的儿童为例。然后,所有预先计算的结果都没有任何用处。如果你需要一些优化和缓存这些东西,它可能更像是一个你需要的应用层缓存,比如memcache,或者存储在缓存表中的预先计算的结果。但是,此缓存是应用程序缓存,它以某种方式与应用程序参数相关(具有不同筛选器的请求将在缓存中使用不同的记录)。

请注意,使用MySQl,您还可以获得一个不错的查询缓存,这将防止相同的查询被计算太多。


推荐