【问题标题】:How do I add new dimensions to a fact table without having to rebuild the table?如何在无需重建表的情况下向事实表添加新维度?
【发布时间】:2021-02-14 00:42:47
【问题描述】:

我是数据仓库的新手,如果这是超级基础,我很抱歉,但我对这个概念很好奇。

示例:假设我有一个存储网站汇总分析的表格(例如,给定日期某个网址的总浏览量)。

dbo.PageFacts

Date Url_Id Page_Views
2020-01-01 1 280
2020-01-01 2 50
2020-01-02 3 10

现在假设我的任务是向该表添加一个新的“Device_Id”列(外键到它自己的维度表),现在该表像这样拆分...

Date Url_Id Device_Id Page_Views
2020-01-01 1 101 180
2020-01-01 1 102 100
2020-01-01 2 101 50
2020-01-02 3 101 10

对于包含数百万条记录的事实表,大多数人是如何做到这一点的?我假设您不想在每次添加新维度时都重新构建它,尤其是当它需要更新聚合值时。

我正在考虑在事实表上创建一个代理键,然后创建一个具有百分比细分(例如 0.75、0.25 等)的单独维度表,然后构建一个将它们连接在一起并计算新值的视图?像这样的...

CREATE TABLE PageFacts (
    PageSurKey INT PRIMARY KEY,
    Date DATE,
    Url_Id INT,
    Page_Views INT
);
CREATE TABLE Device_Pct (
    Id INT PRIMARY KEY,
    PageSurKey INT FOREIGN KEY REFERENCES PageFacts(PageSurKey),
    Device_Id INT,
    Percentage FLOAT
);


CREATE VIEW Device_PageFacts AS
SELECT
    pf.Date,
    pf.Url_Id,
    d.Device_Id,
    SUM(pf.Page_Views * d.Percentage) as Page_Views
FROM PageFacts pf
JOIN Device_Pct d on d.PageSurkey = pf.PageSurkey
GROUP BY pf.Date, pf.Url_Id, d.Device_Id;

这似乎是要走的路(因为添加进一步分割数据的新维度只需要知道要分割的比率),但我不知道是否有更好的做法。任何见解都会有所帮助。提前致谢。

【问题讨论】:

  • 当您使用 ONLINE 时,向表中添加可为空的列是仅元数据更改,根本没有重建。 DW 专家总是说去规范化(我个人认为这是错误的,但这是一个神学论点)所以如果你致力于 DW 概念,你不会把它放在一个单独的表中
  • 如果您以后需要添加越来越多的维度,此方法也会失败,因为您将拥有一堆百分比百分比的连接(您需要在之前以某种方式计算)会减慢您的数据集市。如果你有一些 EDW 层,你可以从某个时间点重建你的数据集市(想想,没有人会用这种新的粒度分析 30 年的数据)。如果您在暂存后只有数据集市,那么您可以从现在开始使用这种新的粒度,因为之前没有任何信息,但您之前已经验证了该数据。
  • 如果您有一个 OLAP 多维数据集在其上旋转的“星形”模式,那么您将别无选择,只能使用新维度 (Device_Id) 重建事实表。否则,任何“拐杖”都是不好的做法,任何额外的 JOIN 都会增加未来数据检索的时间,这对 ROLAP 至关重要。这是我的意见。那么,对于未来,请提前规划解决方案的架构以及解决方案的所有必要维度和可扩展性。
  • @Charlieface 我明白了。是的,我没有考虑非规范化方面。
  • @dzhukov 好电话,是的,额外的连接在这里不是很好的做法,我现在明白了。

标签: sql sql-server database database-design data-warehouse


【解决方案1】:

通常,如果您更改其粒度,您将重建事实表。这是对维度模型的一个非常重要的设计更改,我认为使架构复杂化以避免重建事实表没有任何好处。

如果你愿意,你可以将它作为一个附加事实表引入,但它不会有“百分比”,只是一个普通的事实表:

CREATE TABLE PageDeviceFacts 
(
    Date DATE references DimDate,
    Url_Id INT references DimUrl,
    Device_ID INT references DimDevice,
    Page_Views INT,
    constraint pk_PageDeviceFacts
      primary key (Date,Url_Id,Device_ID)
);

如果是大表,则将 PK 设为非聚集并创建聚集列存储索引

create clustered columnstore index cci_PageDeviceFacts on PageDeviceFacts

旧的 PageFacts 表成为模型中的聚合事实。

【讨论】:

  • 啊,好吧,是的,这是有道理的。使用聚集列存储索引也很有用,我没有考虑过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 2017-08-30
  • 2019-11-18
相关资源
最近更新 更多