如何建模数据库以处理多个时区的计数器

时间:2014-04-25 21:16:32

标签: mysql timezone analytics query-performance

我有一个包含分析信息的表格,即:每页的页面浏览量。

field        type
---------------------------
page_id          long
created_time     long (epoch UTC - rounded by hour)
page_views       long

我将纪元向下舍入到小时(例如:1398456553 ==> 1398456000),允许此表每小时汇总一次信息。

当客户请求他们的数据时,我们可以进行适当的调整,允许他/她在当地时区查看数据。

如果客户端的本地时区是UTC,则查询很简单:

SELECT
    FROM_UNIXTIME(st.`created_time`, '%Y-%m-%d') AS created_at,
    SUM(st.`page_views`) AS page_views
FROM `page_stats` st
WHERE st.`created_time` 
    BETWEEN 1396310400 -- 01 Apr 2014 00:00:00 GMT
    AND 1397088000 -- 10 Apr 2014 00:00:00 GMT
GROUP BY created_at;

如果客户的时区位于其他地方(例如:-03:00),则查询需要更多操作,以调整日期以纠正TZ:

SELECT
    DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(st.`created_time`), '+00:00', '-03:00'), '%Y-%m-%d') AS created_at,
    SUM(st.`page_views`) AS page_views
FROM `page_stats` st
WHERE st.`created_time` 
    BETWEEN 1396321200 -- 01 Apr 2014 03:00:00 GMT
    AND 1397098800 -- 10 Apr 2014 03:00:00 GMT
GROUP BY created_at;

这种方法适用于小时段(<30天),但是当日期范围代表几个月时它会缩小,因为要选择的行数以及因DATE_FORMAT之类的函数需要转换

理想的数据粒度是DAY,但我无法按天创建聚合表,因为每天TZ的按天汇总不同。

对表格进行建模以在大型数据集上提供TZ保真度的正确方法是什么?

值得注意的是,我可以允许这个群体出现一些错误(<2%),也许有些Probabilist Data Structure可能有助于解决问题,但我还无法弄明白。

1 个答案:

答案 0 :(得分:1)

首先,请注意TimeZone!= Offset。请参阅timezone tag wiki

其次,如果您按多个时区中的目标日期进行汇总,则可能只需选择一些相关时区,并将其本地日期预先计算到数据中的唯一列中。然后在查询时很容易聚合。当然,如果你想支持the IANA tzdb中的所有500多个时区,这个策略就不会有用。

另一种策略是舍入以构建另一组表,这些表将项预先聚合为15分钟的桶。为什么15分钟?因为并非所有时区偏移都是按小时计算的。考虑-4:30用于委内瑞拉,+ 5:30用于印度,+5:45用于尼泊尔,+8:45用于澳大利亚部分地区。获得这些预聚合后,您可以在查询时将那些转换为特定客户端时区的详细信息。

最后,您可能会认为像MySQL这样的关系数据库可能不是这项特定工作的最佳工具。 OLAP多维数据集可以很好地工作,因此可以在几个nosql数据库中的任何一个中使用map / reduce函数。您可能希望将数据从MySQL复制到单独的报告商店&#34;或者&#34;数据仓库&#34;,并从那里查询。