我有两个表,记录正从外部源连续插入到这些表中。让我们说这些表保持用户交互的统计数据。当用户单击按钮时,该单击的详细信息(用户,点击时间等)将写入其中一个表。当用户将鼠标悬停在该按钮上时,会向其他表添加包含详细信息的记录。
如果有很多用户不断与系统交互,那么会产生大量数据,而且这些表格会大幅增长。
当我想查看数据时,我希望以小时或每日分辨率查看数据。
是否有一种方法或最佳做法可以按要求的分辨率逐步(按数据收集)连续汇总数据?
还是有更好的解决这类问题的方法吗?
PS。到目前为止我发现的是像Talend这样的ETL工具可以让生活变得轻松。
更新:我目前正在使用MySQL,但无论数据库,环境等如何,我都想知道最佳实践。
答案 0 :(得分:8)
答案 1 :(得分:2)
看看RRDTool。这是一个循环数据库。您可以定义要捕获的指标,但也可以定义存储它的分辨率。
例如,您可以指定拉斯维加斯时间,您可以保留每一秒的信息;过去24小时 - 每分钟;过去一周,每小时等等。
答案 2 :(得分:2)
在切片和聚合数据时(按时间或其他方式),星型模式(Kimball star)是一个相当简单但功能强大的解决方案。假设每次点击我们存储时间(到第二个分辨率),用户信息,按钮ID和用户位置。为了实现简单的切片和切块,我将从预加载的查找表开始,以查找很少更改的对象的属性 - 在DW世界中所谓的维度表。
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
表格。
对于特定用户在某个时间点的每次点击,factClick
表都有一行。我在复合主键中使用了TimeStamp
(第二个分辨率),ButtonKey
和UserKey
来过滤掉来自特定用户的点击速度超过每秒一次的点击次数。请注意Hour
字段,它包含TimeStamp
的小时部分,0-23范围内的整数,以便每小时轻松切片,例如
WHERE [HOUR] BETWEEN 7 AND 9
所以,现在我们必须考虑:
无论表格是仅保留一天或几年的信息 - 都应该进行分区; 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
表中的每一行都有一个计数器,用于从特定地理区域单击特定按钮的每小时。
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)
快速肮脏的建议。
[假设您无法更改基础表,那些表已经记录了添加时间/日期行,并且您确实有权在数据库中创建对象]。
创建视图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>
可选:使用VIEW生成真实表格,如:
CREATE TABLE frozen_data 如 SELECT * FROM VIEW 哪里 时隙号='XXX;
为什么要打扰第1步?你实际上并不需要:只是使用VIEW可能会使事情变得更容易(从SQL的角度来看)。
为什么要打扰第2步?只是一种(可能)减少已经繁忙的表上的负载的方法:如果您可以动态生成DDL,那么您可以生成包含数据“槽”副本的单独表格:然后您可以使用它们。
或者您可以设置一组表格:一天中每小时一个。 创建一个触发器来填充辅助表:触发器的逻辑可以分隔写入哪个表。
每天必须重置这些表:除非您可以在数据库的触发器中生成表。 [我不太可能]。
答案 5 :(得分:0)
尚未给出的建议(到目前为止)可能是使用couchDB或处理非结构化数据的类似数据库概念。
等待!在惊恐地跳过我之前,让我说完。
CouchDB收集非结构化数据(JSON&amp; c);引用网站的技术概述,
解决这个添加问题 结构回到非结构化和 半结构化数据,CouchDB 集成了一个视图模型。意见是 汇总和报告的方法 数据库中的文件,是 建立按需聚合,加入和 报告数据库文件。查看 是动态构建的,不会影响 您可以拥有基础文档 尽可能多的不同视图表示 您喜欢的数据相同。
视图定义严格来说是虚拟的 并且只显示来自的文件 制作当前的数据库实例 他们与数据分开 显示和兼容 复制。定义了CouchDB视图 在特殊设计文件和 可以跨数据库进行复制 像普通文件这样的实例 不仅数据复制 CouchDB,但整个应用程序 设计也复制了。
根据您的要求,我可以告诉您需要
就个人而言,我会做类似的事情:
最后一点只是一个例子。我不知道你打算用它做什么。