0

我经常处理聚合实体或父实体,这些实体具有从其组成成员或子成员派生的属性。例如:

  • 一个对象的byte_countand是从它的两个组成对象的相同属性中计算出来的,而这两个组成对象又是从它们的组成对象中计算出来的。packet_countTcpConnectionTcpStreamTcpPacket

  • 一个Invoices对象可能有一个total基本上是其组成部分InvoiceLineItems价格的 SUM() 的值,其中包含一些运费、折扣和税收逻辑。

在处理数百万个数据包或数百万个发票行项目(我希望!)时,这些派生属性的按需计算——无论是在视图中,还是在更常见的表示逻辑中,如报告或 Web 界面中——通常速度慢得令人无法接受。

在性能问题迫使您动手之前,您如何决定是否将派生属性“提升”到预计算字段?

4

3 回答 3

3

I personally wouldn't denormalize until performance trade-offs force my hand (because the downside of denormalizations are too drastic IMHO), but you might also consider:

  1. Convenience: e.g. if two different client apps want to calculate the same derived attributes, they both have to code up the queries to calculate them. Denormalization offers both client apps the derived attribute in a simpler way.
  2. Stability over time: e.g. if the formula for calculating a derived attribute is changeable, denormalization allows you to capture and store the derived value at a point in time so future calculations will never get it wrong
  3. Simpler queries: adding complexity to the DB structure can mean your Select query is simpler at the client end.
  4. Performance: Select queries on denormalized data can be quicker.

Ref: The Database Programmer: The Argument for Denormalization. Be sure to read as well his article on Keeping Denormalized Values Correct - his recommendation is to use triggers. That brings home the kind of trade-off denormalization requires.

于 2010-02-07T15:34:30.723 回答
1

基本上,你没有。你离开了性能问题迫使你动手。

这是最好的答案,因为在 99% 的情况下,您应该像这样进行预优化,最好是即时计算。

然而,客户端应用程序开发人员带着错误的先入之见进入服务器端是很常见的,例如“按需计算...派生属性... -通常慢得令人无法接受”,而这并不是真的. 这里的正确措辞是“很少慢到无法接受”。

因此,除非您是这方面的专家(数据库开发架构师等),否则您不应该进行过早的优化。等到很明显必须修复,然后查看预聚合。

于 2010-02-05T21:51:11.190 回答
0

实际上,数据的最新程度决定了您如何实施它。

我将假设 2 个简单的状态:当前或非当前。

  • 当前:索引视图、触发器、存储过程以维护聚合表等
  • 不是最新的:报告服务快照、日志传送/复制、数据仓库等

也就是说,我将针对与 prod 中相同数量的数据进行开发,因此我对响应时间有一定的信心。你应该很少对你的代码性能感到惊讶......

于 2010-02-05T21:51:53.097 回答