使用MySQL的物化视图(摘要表)的首选方法

Bur*_*zel 7 php mysql database-design

我正在开发一个工作项目,我需要根据性能原因创建和维护摘要表.我认为正确的术语是物化视图.

我有两个主要原因:

  1. 非规范化

    我尽可能地对表格进行了规范化.因此,有些情况下我必须加入许多表来提取数据.我们使用MySQL Cluster,它在JOIN方面的性能非常差.

    所以我需要创建可以运行更快的SELECT的非规范化表.

  2. 总结数据

    例如,我有一个包含几百万条记录的Transactions表.交易来自不同的网站.应用程序需要生成报告,以显示每日或每月的交易计数以及每个网站的总收入金额.我不希望报告脚本每次都计算这个,所以我需要生成一个按[site,date]分类的摘要表.

    这只是一个简单的例子.我需要生成和维护许多不同类型的汇总表.

在过去,我通过编写几个cron脚本来完成这些工作,以保持每个汇总表的更新.但在这个新项目中,我希望能够实现更优雅,更合适的解决方案.

我更喜欢基于PH​​P的解决方案,因为我不是服务器管理员,当我可以通过我的应用程序代码控制所有内容时,我感觉最舒服.


我考虑过的解决方案:

  1. 复制VIEW

    如果结果表可以表示为单个SELECT查询,我可以生成VIEW.由于它们很慢,因此可以有一个cronjob将此VIEW复制到一个真实的表中.

    但是,这些SELECT查询中的一些可能非常慢,即使对于cronjobs也是如此.如果旧行甚至没有更新,那么重新创建整个摘要数据的效率不高.

  2. 每个摘要表的自定义Cronjobs

    这是我之前使用过的解决方案,但现在我尽量避免使用它.如果有许多汇总表,维护起来可能很麻烦.

  3. MySQL触发器

    可以向主表添加触发器,以便每次有INSERT,UPDATE或DELETE时,汇总表都会相应地更新.

    没有cronjobs,摘要将是实时的.但是,如果需要从头开始重建汇总表,则必须使用另一个解决方案(可能是上面的#1).

  4. 使用ORM挂钩/触发器

    我使用Doctrine作为我的ORM.有一种方法可以添加将在INSERT/UPDATE/DELETE上触发内容的事件侦听器,而后者又可以更新汇总表.从某种意义上说,这个解决方案类似于上面的#3,但我将更好地控制这些触发器,因为它们将在PHP中实现.


实施注意事项:

  1. 完成重建

    我希望避免重建摘要表,以提高效率,并且只更新新数据.但是如果出现问题,我需要能够使用主表上的现有数据从头开始重建汇总表.

  2. 忽略旧数据的更新/删除

    某些摘要可以假定永远不会更新或删除旧记录,但只会插入新记录.摘要过程可以通过假设它不需要检查旧数据的更新来节省大量工作.

    但是,这当然不适用于所有表格.

  3. 记录日志

    我们假设我无法访问或不想使用二进制MySQL日志.

    为了总结新数据,摘要过程只需要记住它汇总的最后记录的最后一个主键ID.下次运行时,它可以汇总该ID之后的所有内容.但是,为了跟踪已更新/删除的旧记录,它需要另一个日志,以便它可以返回并重新汇总该数据.


我将不胜感激任何可以提供帮助的策略,建议或链接.谢谢!

J H*_*zel 3

如上所述,Oracle 中的物化视图与 SQL Server 中的索引视图不同。它们非常酷而且有用。有关详细信息,请参阅http://download.oracle.com/docs/cd/B10500_01/server.920/a96567/repmview.htm

然而 MySql 不支持这些。

您多次提到的一件事是性能不佳。您是否检查过数据库设计的索引是否正确,并对查询运行解释计划以了解它们为何缓慢。请参阅此处http://dev.mysql.com/doc/refman/5.1/en/using-explain.html。当然,这是假设您的服务器已正确调整,您已设置并调整了 mysql,例如缓冲区缓存等。

对于你的直接问题。您听起来想要做的事情正是我们在数据仓库情况下经常做的事情。我们有一个生产数据库和一个数据仓库,可以提取各种信息,对其进行聚合和预计算以加快查询速度。这对你来说可能有点过分了,但你可以决定。根据您为报告定义的延迟(即您需要报告的频率),我们通常会定期(每天、每周等)执行 ETL(提取转换加载)流程,以从生产系统填充 DW。这可以降低对生产系统的影响,并将所有报告移至另一组服务器,这也减轻了负载。在 DW 方面,我通常会设计不同的模式,即使用星型模式。(http://www.orafaq.com/node/2286) 星型模式具有事实表(您想要测量的事物)和维度(您想要按(时间、地理位置、产品类别等聚合度量的事物)) SQL Server 它们还包括一个名为 SQL Server Analysis Services (SSAS) 的附加引擎,用于查看事实表和维度、预先计算和构建 OLAP 数据立方体。在这些数据立方体中,您可以深入分析并查看所有类型的模式、执行数据操作分析和数据挖掘。Oracle 的做法略有不同,但结果是相同的。

您是否想走大约路线实际上取决于业务需求以及您从数据分析中获得多少价值。正如我所说,如果您只有几个汇总表,那么可能会有点过分,但当您仔细思考问题时,您可能会发现一些概念很有帮助。如果您的企业正在寻求商业智能解决方案,那么这是需要考虑的事情。

PS 如果业务需要的话,您实际上可以使用称为 ROLAP 的东西将 DW 设置为“实时”工作。Microstrategy 有一个很好的产品可以很好地解决这个问题。

PPS 您可能还想看看 MS 的 PowerPivot (http://www.powerpivot.com/learn.aspx),我只使用过它,所以我无法告诉您它如何在非常大的数据集上工作。