按日,周,月,年保存统计数据的数据库结构

时间:2009-03-04 13:59:03

标签: mysql database database-design

我必须按网站的用户活动的天,周,月和年收集统计数据。我是数据库设计阶段,我想正确地完成这个阶段,因为它将使我的编码生活更轻松。

我要做的就是每次活动发生时,只需在数据库中将字段中的值增加1即可。那么我可以按每天,每周,每个月和每年提取日期。我的DB应该如何构建?对大多数人来说,这是一个简单的问题。如果这种结构可以扩展,以便可以按其他类别细分,那也是很好的。

我遇到麻烦的是每个月由更多天组成,这些天改变每个日历年。

感谢所有人的帮助或指导。

其他信息:Linux Machine,利用PHP和MySQL

7 个答案:

答案 0 :(得分:19)

不是每天更新计数,每周等,而是每次活动发生时都将一行插入表中:

insert into activities (activity_date, activity_info) 
values (CURRENT_TIMESTAMP, 'whatever');

现在您的报告非常简单,如:

select count(*) from activities
where activity_date between '2008-01-01' and '2008-01-07';

select YEARWEEK(`activity_date`) as theweek, count(*)
group by theweek

答案 1 :(得分:3)

您可以只使用聚合函数将记录添加到表中并SELECT

如果出于某种原因需要保留汇总统计信息,您可以使用:

CREATE TABLE aggregates (type VARCHAR(20), part VARCHAR(10) NOT NULL PRIMARY KEY, activity INT)

INSERT INTO aggregates (type, part, activity)
VALUES ('year', SUBSTRING(SYSDATE(), 1, 4), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

INSERT INTO aggregates (type, part, activity)
VALUES ('month', SUBSTRING(SYSDATE(), 1, 7), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

INSERT INTO aggregates (type, part, activity)
VALUES ('day', SUBSTRING(SYSDATE(), 1, 10), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

这将自动更新现有行,并在需要时插入不存在的行。

答案 2 :(得分:3)

  1. 事件表:id,活动ID,日期时间,用户ID。
  2. 用户表:id,用户名等
  3. 活动表:id,活动名称等
  4. 只需在事件发生时在事件中输入新行。然后,您可以分析事件,但可以操纵时间,日期,用户,活动等。

答案 3 :(得分:2)

首先,您可能想象一个表,因为这将是最规范化的表格。该表只会为您收到的每个匹配项创建一个条目,每行包含该命中的日期/时间。

现在,这样,为了获取每小时,每天,每周等的统计信息,查询很简单,但是您的数据库必须执行一些非常繁重的查询工作。特别是,执行求和,计数或平均值的查询将需要获取所有相关行。

您可以通过预先计算第二个表中所需的计数来确保将该表与第一个表定期同步。问题是,您将负责自己保持缓存同步。

这可能涉及每小时排一排。如果您每天最多只获取24行,那么对一天或一个月进行查询仍然会快得多。

你的另一个建议是从一开始就聚合它,永远不要将每一个匹配存储为一行。你可能会像以前一样,每小时一行。每次点击都会将相关小时数增加一行。您只能将数据放在一个位置,而且已经很好地总结了。

我建议按小时而不是按天计算,这仍然是为您提供支持多个时区的选项。如果您的粒度仅限于当天,那么您没有该选项。

答案 4 :(得分:1)

Tony Andrews的答案是最简单的,但有时在数据仓库应用程序中使用雪花结构:一个表计算所有活动的表,另一个表示每天的活动,另一个表示每月的活动,第三个用于每年的活动。 利用这种结构,可以非常有效地计算任何两个日期之间的活动。 https://en.wikipedia.org/wiki/Snowflake_schema

答案 5 :(得分:1)

使用星型模式设计。 (或者可能是雪花设计)。

Star-Schema Design

您最终会为每个新活动插入事实表。看托尼的建议。

您至少需要两个维度表,一个用于用户,一个用于时间范围。可能存在活动类型的维度,甚至可能是位置。这取决于您想要对数据做什么。

您的问题与时间范围维度表有关。我们称之为“年历”。选择粒度。让我们说一天。年历每天会有一排。主键可以是日期。您的事实表应该包含此主键作为外键,以便使连接更容易。 (无论您是否将其声明为外键都没关系。这只会影响更新过程中的参照完整性。)

在您可以想到的每个报告期内,在年历中包含列。周,月,季度,年等。您甚至可以包含与公司自己的日历相关的报告期。

这是一篇比较ER和DM的文章。我很不寻常,我喜欢这两种方法,为适当的任务选择合适的方法。

http://www.dbmsmag.com/9510d05.html

答案 6 :(得分:0)

您的问题与时间范围维度表有关。我们称之为“年历”。选择粒度。让我们说一天。年历每天会有一排。主键可以是日期。您的事实表应该包含此主键作为外键,以便使连接更容易。 (无论您是否将其声明为外键都没关系。这只会影响更新过程中的参照完整性。)