【问题标题】:Data warehouse for user data - design Q用户数据的数据仓库 - 设计 Q
【发布时间】:2011-02-09 17:33:23
【问题描述】:

如何最好地存储用户数据与日期/时间维度?用例是我试图每天每小时存储用户操作。例如分享数、点赞数、好友数等。我有一个时间表和一个日期表。时间很容易 - 我每天的每个小时都有每一行 = user_id 和列 = 1 到 24。但问题是日期。如果我每天给 = 1 列,那么我每年将有 365 列。我也无法归档数据方式,因为分析也需要过去的数据。其他策略是什么?

【问题讨论】:

    标签: database-design data-warehouse


    【解决方案1】:

    dimDate : 1 row per date
    dimTime : 1 row per minute
    

    一开始你必须说明事实表的“grain”,然后坚持它

    如果grain是一天,那么TimeKey总是指向“23:59”的键。

    如果粒度是一小时,则TimeKey 指向“HH:59”的条目。

    如果grain是一分钟,那么TimeKey指向相应的“HH:MM”

    如果grain是15分钟,那么TimeKey指向各自的“HH:14”、“HH:29”、“HH:44”、“HH:59”

    等等……

    -- How many new friends did specific user gain
    -- in first three months of years 2008, 2009 and 2010
    -- between hours 3 and 5 in the morning
    -- by day of week
    -- not counting holidays ?
    
    select
          DayOfWeek
        , sum(NewFriends) as FriendCount
    from factUserAction as f
    join dbo.dimUser    as u on u.UserKey = f.UserKey
    join dbo.dimDate    as d on d.DateKey = f.DateKey
    join dbo.dimTime    as t on t.TimeKey = f.TimeKey
    where CalendarYear between 2008 and 2010
      and MonthNumberInYear between 1 and 3
      and t.Hour between 3 and 5
      and d.IsHoliday = 'no'
      and UserEmail = 'john_doe@gmail.com' 
    group by DayOfWeek
    order by DayOfWeek ;
    

    【讨论】:

    • 问题:userkey 表 - 我需要在 DW 中为此创建一个单独的 userID 表,还是可以使用存储所有用户信息的同一个 user_id 表?我假设 user_id 将是相同的,所以我可以正确使用同一张表吗?
    • @Rohit; DW 中应该只有一个用户表——希望我正确理解了您的问题。
    • 我想问题是:DW表应该和业务表分开还是使用同一套表?例如:说脸书。他们有一个用户表、照片表等来满足网站的业务需求。然后他们有他们的 DW 用于洞察分析。将这些业务用于其维度的表格也是如此。由于我的网站不大,我想知道是否可以将两者(DW 和业务表)合并在一起。
    • 昨天建模时我有一个问题:“dayOfWeek”等......这些是存储ID还是值?我可以有一个主日期查找表,其中包含所有可能的日期组合作为 PK,并在此处用作 FK。或者我可以在此处存储值,例如 Jan = 1 月、2 月 - 2 月等。
    • @Rohit,价值观。谷歌“Kimball 日期维度”,这是其中之一http://arcanecode.com/2009/11/18/populating-a-kimball-date-dimension/
    【解决方案2】:

    您可以将 日期 存储在维度中,然后添加计算字段,例如 day_of_year。

    在我从事的设计中,我们从来没有比一天更细粒度的时间片,但我不明白为什么不能有一个基于日期-小时的时间维度,作为粒度?

    user_activity_facts(
       time_key references time_dimension(time_key)
      ,user_key references user_dimension(user_key)
      ,measure1
      ,measure2
      ,measure3
      ,primary key(time_key, user_key)
    )
    partition by range(time_key)(
       ...
    )
    

    【讨论】:

    • 嗯,这可以工作,我需要映射一下。所以假设我在下午 1:00 到下午 2:0 有 60 个维度,这意味着要输出下午 1 点到 2 点之间的所有活动,我需要在查询中有 60 个“位置”来捕获每一分钟?
    • 另外这意味着如果我每天需要每小时或每分钟更新,那么我每年将有 525,600 个维度行?我假设每年都有自己的表格正确吗?
    • 我怀疑你会在不到一小时的时间内得到明显的“压缩”。用户每小时执行多少活动?你的术语有点不对劲。你只有一个维度。每行代表特定日期的特定小时。要输出上周五 18:00 到 20:00 之间的所有活动,您将执行“日期 '2011-02-04 18:00:00' 和日期 '2011-02-04 20:00:00'之间的 xx”
    • 很多(如果不是大多数)DBMS 支持不同类型的 DATE 和 TIME。为日期和时间设置单独的属性通常是有意义的。您可以有一个单独的时间维度表以及一个日期维度,这样您就不必在日期表中创建所有这些额外的行。
    • 是的,你是对的。我只需要与白天一起工作就被宠坏了。考虑到这些数字,我可以看到在一个表中组合天+小时的唯一优势是,如果您经常按日期和小时查询,那么维度的索引选择性会更好 -> 事实上。但无论如何,尺寸增加很可能会带走优势:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    相关资源
    最近更新 更多