查询涉及时间维度的数仓数据

Posted

技术标签:

【中文标题】查询涉及时间维度的数仓数据【英文标题】:Querying a data warehouse data involving time dimension 【发布时间】:2011-08-14 11:26:50 【问题描述】:

我有两个时间维度表

日期(每一天的唯一行) 一天中的时间(一天中每一分钟的唯一行)

给定这个模式,如果一个人想要检索过去 X 小时的事实,其中 X 可以是任何大于 0 的数字,查询会是什么样子。

当开始时间和结束时间恰好在一年中的两个不同日子时,事情就开始变得棘手了。

编辑:我的事实表没有时间戳

【问题讨论】:

您可能会创建一个时间列(使用视图,或“with”,或仅与子查询连接)然后使用它。但是时间命令变化很大,知道你正在使用什么数据库是至关重要的。 我目前正在使用 mysql,但我必须在不久的将来使其至少与 sqlserver、oracle 和 sqllite 一起使用 【参考方案1】:

事实表确实具有(并且应该具有)原始时间戳,以避免在一天的边界上发生奇怪的按时间查询。奇怪意味着在 WHERE 子句中有某种复杂的日期时间函数。

在大多数 DW 中,这类查询非常少见,但您似乎将数据流式传输到 DW 并同时使用它进行报告。

所以我建议:

    在事实表中引入完整的时间戳。

    对于旧记录,从日期和时间键重新创建时间戳。

DW 查询都是关于在 WHERE 子句中没有任何函数,或者如果必须使用函数,请确保它是 SARGABLE。

【讨论】:

【参考方案2】:

Start DateEnd Date 列转换为TIMESTAMP 并填充它们可能会更好。

切片表需要使用适当的interval BETWEEN Start Date AND End Date。在 Oracle 中,interval 类似于SYSDATE - (4/24)SYSDATE - NUMTODSINTERVAL(4, 'HOUR')

这也可以改写为:

Start Date <= (SYSDATE - (4/24)) AND End Date >= (SYSDATE - (4/24))

【讨论】:

【参考方案3】:

在我看来,鉴于您拥有的当前架构,您需要从时间维度表中检索符合您的搜索条件的适当时间 ID,然后在事实表中搜索匹配的行。根据您的时间维度的粒度,您可能需要检查执行以下任一操作的性能(SQL Server 示例):

    子选择

    SELECT X FOO WHERE TIMEID IN (SELECT ID FROM DIMTIME WHERE HOUR >= DATEPART(HOUR, CURRENT_TIMESTAMP()) 和 DATEID IN (SELECT ID FROM DIMDATE WHERE DATE = GETDATE())

    内连接

    SELECT X FOO INNER JOIN DIMTIME ON TIMEID = DIMTIME.ID WHERE HOUR >= DATEPART(HOUR, CURRENT_TIMESTAMP()) INNER JOIN DIMDATE ON DATEID = DIMDATE.ID WHERE DATE = GETDATE()

这些都不是真正有吸引力的选择。

您是否考虑过查询的多维数据集可能用于汇总分析,而不一定用于“最后 X”分析?

如果这不是“汇总”多维数据集,我会同意其他海报的观点,即您应该使用更好的键重新标记事实表,并且如果您确实打算经常搜索下班时间,您可能也应该将其包含在事实表中,因为任何其他尝试都可能使查询不可解析(请参阅What makes a SQL statement sargable?)。

Microsoft 在http://msdn.microsoft.com/en-us/library/aa902672%28v=sql.80%29.aspx 建议:

与其他维度表中使用的代理键相比,日期和时间维度键应该是“智能的”。日期维度的建议键采用“yyyymmdd”形式。这种格式很容易让用户记住并合并到查询中。对于按日期划分为多个表的事实表,它也是推荐的代理键格式。

祝你好运!

【讨论】:

以上是关于查询涉及时间维度的数仓数据的主要内容,如果未能解决你的问题,请参考以下文章

大数据开发工程师需要了解的数仓中的维度设计

大数据开发工程师需要了解的数仓中的维度设计

大数据开发工程师需要了解的数仓中的维度设计

大数据开发工程师需要了解的数仓中的维度设计

数据仓库数仓建模之星型模型与维度建模

数据模型(维度建模)