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

Chr*_*rga 16 php mysql field

如果以前曾经问过这个问题,我很抱歉,但我似乎无法找到一个关于我在飞行中计算与存储数据库中存储字段的问题的答案.

我读了一些文章,建议最好尽可能计算,但我想知道这是否仍然适用于以下2个例子.

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

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

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

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

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

我知道存储任何可以计算的东西都是多余的,但是我担心计算字段或计数记录可能会比在字段中存储数据要慢.如果不是那么请告诉我,我只想了解何时使用这两种方法.在一个小规模上,我想这无关紧要,但像Facebook这样的应用程序,他们真的会计算每次有人查看你的个人资料时你拥有的朋友数量,还是只将它存储为一个字段?

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

提前致谢,

基督教

Osw*_*ald 12

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


reg*_*ero 8

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

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

现在,如果我们采用你的第二个例子,它真的不确定某人不会想要某一天在类别计算上添加一些过滤器.例如,只接受介于2和5之间的子项.然后,所有预先计算的结果都不起作用.如果你需要对这些东西进行一些优化和缓存,它可能更像是你需要的应用程序层缓存,比如memcache,或者存储在缓存表中的预先计算结果.但是这个缓存是一个应用程序缓存,它以某种方式与您的应用程序参数相关(具有不同过滤器的请求将在缓存中使用不同的记录).

请注意,使用MySQl,您还可以获得一个很好的查询缓存,这将阻止相同的查询计算得太多.


Ron*_*nis 8

其他人已经涉及技术方面,所以让我给你另一个观点:

对于您介绍的每个异常,您都会使开发过程变慢.

非规范化数据,聚合,预加入数据等都是使开发变得非常复杂的事例,因为您必须:

  • 每当更改详细表时,请继续重写聚合逻辑
  • 测试更多(通常看似无关的应用程序部分)
  • 写更多文档
  • 使升级和补丁变得复杂

在许多情况下,它是值得的,在某些情况下是绝对必要的,但如果你不必要的话,牺牲开发速度将是非常愚蠢的.