不同分辨率的数据

时间:2010-01-07 16:43:43

标签: database data-warehouse etl summarization

我有两个表,记录正从外部源连续插入到这些表中。让我们说这些表保持用户交互的统计数据。当用户单击按钮时,该单击的详细信息(用户,点击时间等)将写入其中一个表。当用户将鼠标悬停在该按钮上时,会向其他表添加包含详细信息的记录。

如果有很多用户不断与系统交互,那么会产生大量数据,而且这些表格会大幅增长。

当我想查看数据时,我希望以小时或每日分辨率查看数据。

是否有一种方法或最佳做法可以按要求的分辨率逐步(按数据收集)连续汇总数据?

还是有更好的解决这类问题的方法吗?

PS。到目前为止我发现的是像Talend这样的ETL工具可以让生活变得轻松。

更新:我目前正在使用MySQL,但无论数据库,环境等如何,我都想知道最佳实践。

6 个答案:

答案 0 :(得分:8)

答案 1 :(得分:2)

看看RRDTool。这是一个循环数据库。您可以定义要捕获的指标,但也可以定义存储它的分辨率。

例如,您可以指定拉斯维加斯时间,您可以保留每一秒的信息;过去24小时 - 每分钟;过去一周,每小时等等。

它广泛用于收集GangliaCacti等系统中的统计信息。

答案 2 :(得分:2)

在切片和聚合数据时(按时间或其他方式),星型模式(Kimball star)是一个相当简单但功能强大的解决方案。假设每次点击我们存储时间(到第二个分辨率),用户信息,按钮ID和用户位置。为了实现简单的切片和切块,我将从预加载的查找表开始,以查找很少更改的对象的属性 - 在DW世界中所谓的维度表。

pagevisit2_model_02

dimDate表每天有一行,其中包含描述特定日期的属性(字段)数。该表可以提前多年预先加载,如果它包含DaysAgo, WeeksAgo, MonthsAgo, YearsAgo等字段,则应每天更新一次;否则它可以“加载并忘记”。 dimDate允许按日期属性轻松切片,例如

WHERE [YEAR] = 2009 AND DayOfWeek = 'Sunday'

对于十年的数据,该表只有~3650行。

dimGeography表预先加载了感兴趣的地理区域 - 行数取决于报告中所需的“地理分辨率”,它允许数据切片,如

WHERE Continent = 'South America'

加载后,很少更改。

对于网站的每个按钮,dimButton表中有一行,因此查询可能有

WHERE PageURL = 'http://…/somepage.php'

dimUser表每个注册用户有一行,一旦用户注册就应该加载一个新的用户信息,或者至少新的用户信息应该在任何其他用户之前的表中交易记录在事实表中。

要记录按钮点击次数,我将添加factClick表格。

pagevisit2_model_01

对于特定用户在某个时间点的每次点击,factClick表都有一行。我在复合主键中使用了TimeStamp(第二个分辨率),ButtonKeyUserKey来过滤掉来自特定用户的点击速度超过每秒一次的点击次数。请注意Hour字段,它包含TimeStamp的小时部分,0-23范围内的整数,以便每小时轻松切片,例如

WHERE [HOUR] BETWEEN 7 AND 9

所以,现在我们必须考虑:

  • 如何加载表格?定期 - 可能每小时或每隔几分钟 - 来自使用ETL工具的博客,或使用某种事件流过程的低延迟解决方案。
  • 将信息保存在表中多长时间?

无论表格是仅保留一天或几年的信息 - 都应该进行分区; ConcernedOfTunbridgeW在他的回答中解释了分区,所以我会在这里跳过它。

现在,每个不同属性(包括日和小时)切片和切块的几个例子

为了简化查询,我将添加一个视图来展平模型:

/* To simplify queries flatten the model */ 
CREATE VIEW vClicks 
AS 
SELECT * 
FROM factClick AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimUser AS u ON u.UserKey = f.UserKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

查询示例

/* 
Count number of times specific users clicked any button  
today between 7 and 9 AM (7:00 - 9:59)
*/ 
SELECT  [Email] 
       ,COUNT(*) AS [Counter] 
FROM    vClicks 
WHERE   [DaysAgo] = 0 
        AND [Hour] BETWEEN 7 AND 9 
        AND [Email] IN ('dude45@somemail.com', 'bob46@bobmail.com') 
GROUP BY [Email] 
ORDER BY [Email]

假设我对User = ALL的数据感兴趣。 dimUser是一张大表,因此我会在没有它的情况下制作视图,以加快查询速度。

/* 
Because dimUser can be large table it is good 
to have a view without it, to speed-up queries 
when user info is not required 
*/ 
CREATE VIEW vClicksNoUsr 
AS 
SELECT * 
FROM factClick AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

查询示例

/* 
Count number of times a button was clicked on a specific page 
today and yesterday, for each hour. 
*/ 
SELECT  [FullDate] 
       ,[Hour] 
       ,COUNT(*) AS [Counter] 
FROM    vClicksNoUsr 
WHERE   [DaysAgo] IN ( 0, 1 ) 
        AND PageURL = 'http://...MyPage' 
GROUP BY [FullDate], [Hour] 
ORDER BY [FullDate] DESC, [Hour] DESC



假设对于聚合,我们不需要保留特定的用户信息,但只对日期,小时,按钮和地理位置感兴趣。 factClickAgg表中的每一行都有一个计数器,用于从特定地理区域单击特定按钮的每小时。

pagevisit2_model_03

factClickAgg表可以按小时加载,甚至可以在每天结束时加载 - 具体取决于报告和分析的要求。例如,假设表格在每天结束时(午夜后)加载,我可以使用类似的东西:

/* At the end of each day (after midnight) aggregate data. */ 
INSERT  INTO factClickAgg 
        SELECT  DateKey 
               ,[Hour] 
               ,ButtonKey 
               ,GeographyKey 
               ,COUNT(*) AS [ClickCount] 
        FROM    vClicksNoUsr 
        WHERE   [DaysAgo] = 1 
        GROUP BY DateKey 
               ,[Hour] 
               ,ButtonKey 
               ,GeographyKey

为了简化查询,我将创建一个视图来展平模型:

/* To simplify queries for aggregated data */ 
CREATE VIEW vClicksAggregate 
AS 
SELECT * 
FROM factClickAgg AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

现在我可以查询汇总数据,例如按天:

/* 
Number of times a specific buttons was clicked 
in year 2009, by day 
*/ 
SELECT  FullDate 
       ,SUM(ClickCount) AS [Counter] 
FROM    vClicksAggregate 
WHERE   ButtonName = 'MyBtn_1' 
        AND [Year] = 2009 
GROUP BY FullDate 
ORDER BY FullDate

或者还有一些选项

/* 
Number of times specific buttons were clicked 
in year 2008, on Saturdays, between 9:00 and 11:59 AM 
by users from Africa 
*/ 

SELECT  SUM(ClickCount) AS [Counter] 
FROM    vClicksAggregate 
WHERE   [Year] = 2008 
        AND [DayOfWeek] = 'Saturday' 
        AND [Hour] BETWEEN 9 AND 11 
        AND Continent = 'Africa' 
        AND ButtonName IN ( 'MyBtn_1', 'MyBtn_2', 'MyBtn_3' )

答案 3 :(得分:0)

您可以使用PI或Historian等历史数据库。那些可能比你想要花在这个项目上的钱多,所以你可能想要查找一个免费软件替代品,比如Realtime and History Database Package

答案 4 :(得分:0)

快速肮脏的建议。

[假设您无法更改基础表,那些表已经记录了添加时间/日期行,并且您确实有权在数据库中创建对象]。

  1. 创建一个VIEW(或几个VIEWS),其上有一个逻辑字段,通过在表格中截断日期来生成唯一的“slot-number”。类似的东西:
  2. 创建视图AS SELECT a,b,c,SUBSTR(date_field,x,y)slot_number     从           表;

    上面的示例已经简化,您可能希望从日期+时间添加更多元素。

    [例如,假设日期为'2010-01-01 10:20:23,111',您可能会将密钥生成为'2010-01-01 10:00':所以您的分辨率为1小时]。< / p>

    1. 可选:使用VIEW生成真实表格,如:

      CREATE TABLE frozen_data     如     SELECT * FROM VIEW     哪里     时隙号='XXX;

    2. 为什么要打扰第1步?你实际上并不需要:只是使用VIEW可能会使事情变得更容易(从SQL的角度来看)。

      为什么要打扰第2步?只是一种(可能)减少已经繁忙的表上的负载的方法:如果您可以动态生成DDL,那么您可以生成包含数据“槽”副本的单独表格:然后您可以使用它们。

      或者您可以设置一组表格:一天中每小时一个。 创建一个触发器来填充辅助表:触发器的逻辑可以分隔写入哪个表。

      每天必须重置这些表:除非您可以在数据库的触发器中生成表。 [我不太可能]。

答案 5 :(得分:0)

尚未给出的建议(到目前为止)可能是使用couchDB或处理非结构化数据的类似数据库概念。

等待!在惊恐地跳过我之前,让我说完。

CouchDB收集非结构化数据(JSON&amp; c);引用网站的技术概述,

  

解决这个添加问题   结构回到非结构化和   半结构化数据,CouchDB   集成了一个视图模型。意见是   汇总和报告的方法   数据库中的文件,是   建立按需聚合,加入和   报告数据库文件。查看   是动态构建的,不会影响   您可以拥有基础文档   尽可能多的不同视图表示   您喜欢的数据相同。

     

视图定义严格来说是虚拟的   并且只显示来自的文件   制作当前的数据库实例   他们与数据分开   显示和兼容   复制。定义了CouchDB视图   在特殊设计文件和   可以跨数据库进行复制   像普通文件这样的实例   不仅数据复制   CouchDB,但整个应用程序   设计也复制了。

根据您的要求,我可以告诉您需要

  • 以可靠的方式收集大量数据
  • 优先考虑的是速度/可靠性,而不是一旦进入系统就构建数据,也不是维护/检查收集的结构属性(即使您错过了1ms的用户数据,也可能不是这样的大问题)
  • 当数据库 out
  • 时,您需要结构化数据

就个人而言,我会做类似的事情:

  • 在客户端缓存收集的数据并将其以突发方式保存到couchdb
  • 取决于工作负载,保持一个db的集群(再次,为此设计了couchdb)在彼此之间保持同步
  • 每个间隔都有一个服务器生成您需要的东西的视图(即每小时等),而其他人继续收集数据
  • 将这些(现在结构化的)视图保存到适当的数据库中,以便操作和使用SQL工具或其他任何

最后一点只是一个例子。我不知道你打算用它做什么。