1

我有一个规范化的数据库,需要经常生成基于 Web 的报告,其中涉及跨多个表的连接。这些查询花费的时间太长,所以我想保持计算结果,以便我可以快速加载页面。我正在总结的表格经常更新,我需要总结来反映迄今为止的所有更新。

所有表都有自动增量主整数键,我几乎总是添加新行,并且可以安排在它们发生变化时清除计算结果。

我遇到了一个类似的问题,我需要通过安排迭代表中的每一行来对单个表进行摘要,并跟踪迭代器状态和所见的最高主要敏锐度(即“高水位”)。这对于一张桌子来说很好,但对于多张桌子,我最终会为每张桌子保留一个高水位值,这感觉很复杂。或者,我可以非规范化到一个表(具有相当广泛的应用程序更改),这感觉是倒退了一步,并且可能会将我的数据库大小从大约 5GB 更改为大约 20GB。

(我目前正在使用 sqlite3,但 MySQL 也是一种选择)。

4

5 回答 5

2

我看到两种方法:

  1. 您将数据移动到单独的数据库中,进行非规范化,进行一些预先计算,以优化它以实现快速访问和报告(听起来像一个小型数据仓库)。这意味着您必须考虑一些将数据从源复制并转换到目标的作业(脚本、单独的应用程序等)。根据您希望完成复制的方式(完整/增量)、复制频率和数据模型的复杂性(源和目标),可能需要一段时间来实现然后优化过程。它的优点是使您的源数据库保持不变。

  2. 您保留当前数据库,但将其非规范化。正如您所说,这可能意味着应用程序的逻辑发生了变化(但您可能会找到一种方法来最大限度地减少对使用数据库的逻辑的影响,您比我更了解这种情况:))。

于 2009-06-04T10:30:29.030 回答
1

您可以创建触发器。

只要其中一个计算值发生更改,您就可以执行以下操作之一:

  • 更新计算字段(首选)
  • 重新计算汇总表
  • 存储需要重新计算的标志。下次您需要计算值时,请先检查此标志,并在必要时重新计算

例子:

CREATE TRIGGER update_summary_table UPDATE OF order_value ON orders 
BEGIN
  UPDATE summary 
    SET total_order_value = total_order_value 
                          - old.order_value 
                          + new.order_value 
    // OR: Do a complete recalculation
    // OR: Store a flag
END;

有关 SQLite 触发器的更多信息:http ://www.sqlite.org/lang_createtrigger.html

于 2009-06-04T10:39:52.037 回答
1

报告是否可以增量刷新,或者是否完全重新计算以重做报告?如果必须完全重新计算,那么您基本上只想缓存结果集,直到需要下一次刷新。您可以创建一些表来包含报告输出(和元数据表来定义可用的报告输出版本),但大多数情况下这是多余的,您最好将查询结果保存到文件或其他缓存存储中.

如果它是增量刷新,那么无论如何您都需要 PK 范围,因此您需要像高水位标记数据这样的东西(除非您可能想要存储最小/最大对)。

于 2009-06-04T13:27:04.040 回答
0

最后,我安排了一个程序实例来进行所有数据库更新,并在其堆中维护摘要,即根本不在数据库中。这在这种情况下非常有效,但如果我有多个程序进行数据库更新,那就不合适了。

于 2009-06-08T15:43:55.257 回答
0

你还没有提到你的索引策略。我会先看一下 - 确保您的索引覆盖。

那么我认为讨论的触发选项也是一个非常好的策略。

另一种可能性是具有适合高性能报告的模型(例如,Kimball 模型)的数据仓库的常规填充。

于 2009-06-08T15:54:45.163 回答