聚合数据表

时间:2012-07-26 17:35:56

标签: mysql

我正在构建一个大型数据库的前端(数百万行)。数据是不同公司负荷的用水量,表格如下:

id | company_id | datetime            | reading | used | cost
=============================================================
1  | 1          | 2012-01-01 00:00:00 | 5000    | 5    | 0.50
2  | 1          | 2012-01-01 00:01:00 | 5015    | 15   | 1.50
....

在前端,用户可以选择他们想要查看数据的方式,例如:6小时增量,每日增量,每月等。快速完成此操作的最佳方法是什么。鉴于数据变化如此之多以及任何一组数据将被看到的次数,在memcahce或类似的东西中缓存查询数据几乎是毫无意义的,并且由于存在太多变量,因此无法预先构建数据。

我认为使用某种agregate聚合表可以使用具有完全相同结构的readingsreadings_6hreadings_1d等表,只是已经聚合了。

如果这是一个可行的解决方案,那么保持聚合表最新和准确的最佳方法是什么。除了来自仪表的数据外,该表格是只读的。用户无需更新或写入。

许多可能的解决方案包括:

1)坚持使用群组/聚合功能进行查询

2)进行基本选择并保存

SELECT `company_id`, CONCAT_WS(' ', date(`datetime`), '23:59:59') AS datetime, 
MAX(`reading`) AS reading, SUM(`used`) AS used, SUM(`cost`) AS cost 
FROM `readings`
WHERE `datetime` > '$lastUpdateDateTime'
GROUP BY `company_id`

3)重复密钥更新(不确定如何在此处完成聚合,同时确保数据准确无法计算两次或丢失行。

INSERT INTO `readings_6h` ... 
SELECT FROM `readings` .... 
ON DUPLICATE KEY UPDATE .. calculate...

4)其他想法/建议?

我目前正在做选项2,这需要大约15分钟将+ - 100k行聚合成+ - 30k行,超过4个表(_6h,_1d,_7d,_1m,_1y)

TL; DR查看/存储无法有效缓存的众多报告的汇总数据的最佳方法是什么。

1 个答案:

答案 0 :(得分:10)

这个功能最好由名为materialized view的功能提供,MySQL不幸缺少这个功能。您可以考虑迁移到其他数据库系统,例如PostgreSQL。

有一些方法可以使用存储过程,触发器和事件在MySQL中模拟实体化视图。您创建一个更新聚合数据的存储过程。如果必须在每个插入上更新聚合数据,则可以定义调用该过程的触发器。如果必须每隔几小时更新一次数据,则可以定义MySQL scheduler event或cron作业。

有一种组合方法,类似于您的选项3,不依赖于输入数据的日期;想象一下如果一些新数据到达时刻太晚并且没有进入聚合会发生什么。 (你可能没有这个问题,我不知道。)你可以定义一个触发器,将新数据插入“backlog”,并让程序仅从积压中更新聚合表。

本文详细介绍了所有这些方法:http://www.fromdual.com/mysql-materialized-views