【问题标题】:How should I keep accurate records summarising multiple tables?我应该如何保存汇总多个表的准确记录?
【发布时间】:2010-10-31 06:45:51
【问题描述】:

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

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

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

(我目前使用的是 sqlite3,但 MySQL 也是一个选项)。

【问题讨论】:

    标签: sql algorithm sqlite normalization


    【解决方案1】:

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

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

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

    【讨论】:

    • 哦,我先检查了我的索引 :) 如果您已经让查询以您认为的最快速度运行,那么查看这种事情是没有意义的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        您可以创建触发器。

        只要计算值之一发生变化,您就可以执行以下操作之一:

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

        示例:

        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

        【讨论】:

        • 问题在于每次更新时从头开始再次执行查询会占用过多的 CPU 时间(并可能导致数据库锁争用过多)。
        • 这就是我添加第一个和第三个选项的原因:要么只更新那些必要的字段,要么写一个需要更新的标记并将重新计算推迟到以后。跨度>
        【解决方案5】:

        我看到了两种方法:

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

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

        【讨论】:

        • #1 听起来很标准,也很合适。暂存区 --> 标准化区 --> 报告区
        • 是的,这就是我把它放在第一位的原因:)
        猜你喜欢
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多