在数据库中存储计算数据的错误做法?

Ada*_*son 11 best-practices computed-column

将计算出的数据存储在每一行中是不好的做法,还是每次从数据库读取时在应用程序层进行计算更好。

存储在数据库中避免了多次计算的需要,但如果出现错误,则需要更新数据,而不仅仅是更改应用程序级别的计算。

我认为后者更好,但是有一般的经验法则吗?

例如,我需要计算食物的每日总营养摄入量。因此,各种portionsenergyfoods。我可以portion根据相应计算能量food并将energy每个的能量存储portionportions表中,或者我可以food每次从与相应的连接中计算。

您可以想象,如果您必须在很长一段时间内计算年平均值、月平均值、日平均值等,它可能会变得非常笨拙。

如果使用物化视图,每次旧数据(例如一周或更早)根据触发器或类似内容进行更新时都会重新计算,那又如何呢?

Bas*_*que 13

如果计算机无限快,那么,不,您永远不会存储可以从数据库中的其他列计算的值。存储计算值违反了数据库规范化

示例包括:

  • 所述扩展的成本上携带价格和数量字段发票行。
  • 发票行的总成本。

在现实世界中,我们有时确实会选择违反规范化。动机通常是出于性能原因。千万不要没有深思熟虑,并希望与其他 DBA 或数据库开发人员协商。并始终彻底记录您的决定及其具体动机。

有一般的经验法则吗?

是:标准化,并测试/profile。

始终从标准化设计开始。加载虚假数据,测试性能。验证任何发现的瓶颈确实是由于您的即时计算。


RDF*_*ozz 7

额外的考虑因素:某些值是根据不断增加的其他值计算得出的。示例:客户的当前余额是通过添加所有费用并减去所有付款来计算的。如果客户已活跃多年,则每次要显示其余额时可能需要访问大量行。

当然,所有相同的问题(即时计算的时间/资源,与出现问题时的重新计算成本)仍然适用。这里的区别在于计算成本随着时间的推移而增加。

我使用的系统使用了混合方法:当新的费用或付款进入帐户时,客户余额被存储和修改,但在每晚的过程中从头开始重新计算价值。


Kon*_*bas 5

这取决于。有些值最好立即计算,有些值最好推迟到需要时再计算。

有一次,我必须预先计算每两个连续 GPS 点之间的距离,并增加与点数据一起存储的里程表值。这些分布计算使我能够通过从最后一个里程表值中减去该范围内的第一个里程表值来获得路线上任意两个任意点之间的距离。按需计算距离需要花费大量时间,这是不可接受的。但这些数据并不重要,如果错过了某个点,里程表/距离值仍然具有可接受的精度。

在我看来,如果你可以预先计算一些数据来加速一些频繁和繁重的查询 - 预先计算它们。如果您想在没有真正必要的情况下提前进行预计算 - 不要浪费 CPU 和 IO 资源。