2

我正在构建一个Google Analytics应用程序,用于跟踪公司营销活动的转化。转换是如果他们去超市购买产品。如果公司是亨氏,他们可能会遇到的不同产品的广告,因此广告活动可能是:适用于多个数据排列的数据模型设计(RDBMS)

  • 焗豆
  • 番茄汤
  • 番茄酱

这些都是在线广告系列,使他们能够有不同的介质如:

  • 网站
  • Facebook的
  • Flash横幅广告
  • 移动应用广告

如果有人买了产品,它通过一个超市买的,如:

  • 沃尔玛
  • 阿斯达
  • Safeway
  • Kroger

我们正在跟踪所有这些转化。分析应用程序需要显示上述任意组合的转化数据。所以,例如,我可能需要显示转​​换...

  • 烤豆。
  • 来自Facebook页面的烤豆。
  • 为超市沃尔玛,但为所有活动&媒介。
  • 为沃尔玛从Facebook页面,但所有的运动。
  • 用于通过Flash Banner Ad和Safeway制作的番茄酱。

为了使分析速度更快,我们避免处理原始数据(数百万条记录),但存储每天存储的数据的汇总版本。因此,在9月12日的报告中,我可以保存我们有12次转化为焗豆,6次转化(对于所有产品)通过网站进行,沃尔玛有8次转化,这些转化可以分为3个单独的表格(称为Campaigns,媒体和超市)。但是,如果我需要知道通过Facebook页面和沃尔玛制作的番茄酱转换,存储在单独的表格中显然不起作用。

我很努力想出一个可以支持上述的数据模型。我正在使用标准的关系数据库(MySQL)。也许有更好的策略来处理这个问题。

回答

3

是的,有一个更好的策略。它被称为尺寸建模或星型模式。

您存储一张表,名为事实表,其中包含Campaign,Medium和Supermarket的列。

对于这些属性中的每一个,事实表中的列都是尺寸表的外键。每个Campaigns,Mediums和Supermarkets的一个维度表。

你的情况,以避免数百万行的,你可以第四列添加到事实表,conversions。在进行转换时增加计数(而不是添加另一行)。

下面是一个例子表:

CREATE TABLE FactTable (
    campaign_id INT, 
    medium_id INT, 
    supermarket_id INT, 
    conversions INT, 
    PRIMARY KEY (campaign_id, medium_id, supermarket_id), 
    FOREIGN KEY (campaign_id) REFERENCES Campaigns(campaign_id), 
    FOREIGN KEY (medium_id) REFERENCES Mediums(medium_id), 
    FOREIGN KEY (supermarket_id) REFERENCES Supermarkets(supermarket_id) 
); 

然后你就可以查询所有的转换:

  • 用于焗豆。

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    WHERE campaign = 'Baked Beans'; 
    
  • 从Facebook页面烘烤的豆类。

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    JOIN Mediums USING (medium_id) 
    WHERE campaign = 'Baked Beans' AND medium = 'Facebook'; 
    
  • 的超市沃尔玛,但对于所有的广告活动&介质。

    SELECT SUM(conversions) FROM FactTable 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE supermarket = 'Walmart'; 
    
  • 沃尔玛从Facebook页面,但所有的运动。

    SELECT SUM(conversions) FROM FactTable 
    JOIN Mediums USING (medium_id) 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE medium = 'Facebook' AND supermarket = 'Walmart'; 
    
  • 用于通过Flash Banner Ad和Safeway制作的番茄酱。

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    JOIN Mediums USING (medium_id) 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE campaign = 'Ketchup' AND medium = 'Flash Banner Ad' AND supermarket = 'Safeway'; 
    

退房books by Ralph Kimball更多关于三维建模。

+1

容易在五大最佳答案#2我曾经有过!非常感谢:-) – 2014-09-04 22:32:32

+0

不仅是一个很好的答案,但非常好。我想补充一点,在很多情况下,客户端应用程序嵌入在显示的名称控制整数ID(或某种UUID的一个公共API)。因此,不需要连接...只需对id(s)上的WHERE子句进行过滤。甚至更快。 – NaturalData 2014-09-06 04:17:50

+0

@NaturalData,是的,这是一个很好的优化,我正给加入,因为它说明了维度表的作用非常好。 – 2014-09-06 07:46:23

2

我认为,试图操纵你的数据结构,以避免处理的原始数据,都将增加复杂性并降低了灵活性,很少真正的好处。通过适当的索引和适当调整的查询,查询数百万条记录应该花费很少的时间。我在多个字段中查询了5亿条记录,并在20ms以内获得了结果。

把你的精力投入到调整,而不是设计新的数据结构,以及你应该心存感激时,不管是谁消费这些分析在一些稍微不同的格式,使您精心策划设计过时需要的数据。