代码之家  ›  专栏  ›  技术社区  ›  Rachel

如何使用维度中的代理项键填充事实表

  •  3
  • Rachel  · 技术社区  · 6 年前

    请您帮助理解如何使用维度中的代理键填充事实表。

    我有以下事实表和维度:

    索赔事实

    合同DIM\U SK 索赔项目 会计DIM\U SK 索赔编号 索赔金额

    合同DIM

    合同DIM\U SK(PK) 合同编号(BK) 报告期(BK) 密码 名称

    会计DIM

    交易编号(BK) 报告期(PK) 交易代码 货币代码 (我应该在此处添加ContractNbr吗?OLTP中的原始表中有它)

    ClaimDim公司

    CalimsDim\u Sk(PK) 校准br(黑色) 报告期(BK) 索赔说明 索赔名称 (我应该在此处添加ContractNbr吗?OLTP中的原始表中有它)

    我将数据加载到事实表的逻辑如下:

    1. 首先,我将数据加载到维度中(使用代理键创建为标识列)
    2. 从事务模型(OLTP)中,事实表将填充度量值(ClaimNbr和claimmount)

    3. 我不知道如何用维度的SKs填充事实表,如何知道将我从维度中提取的键放在哪里,放在事实表中的哪一行(哪个键属于这个claimNBR?) 我是否应该在所有维度中添加合同编号,并在加载事实密钥时将它们连接在一起?

    做这件事的正确方法是什么? 请帮忙, 非常感谢。

    1 回复  |  直到 6 年前
        1
  •  8
  •   RADO    6 年前

    通常的工作方式:

    1. 在您的维度中,您将拥有“自然密钥”(又名“业务密钥”)——来自外部系统的密钥。例如,合同编号。然后为表创建合成(代理)键。
    2. 在事实表中,所有键最初也必须是“自然键”。例如,合同编号。要连接到事实数据表的每个维度都必须存在这样的键。有时,一个维度可能需要几个自然键(它们共同表示维度表的“粒度”级别)。例如,如果以州-市级别为模型,则位置可能需要州和市关键帧。
    3. 将dim表连接到自然键上的事实表,并从结果中从事实中省略自然键,然后从dim中选择代理键。我通常执行左连接(事实左连接dim),以控制不匹配的记录。我还一个接一个地加入dims(以便更好地控制发生的事情)。

    基本示例(使用T-SQL)。假设您有以下两个表:

    Table OLTP.Sales
    (   Contract_BK, 
        Amount, 
        Quanity)
    
    Table Dim.Contract
    (   Contract_SK,
        Contract_BK,
        Contract Type)
    

    要交换密钥,请执行以下操作:

    SELECT
         c.Contract_SK
        ,s.Amount
        ,s.Quantity
    INTO
        Fact.Sales
    FROM
        OLTP.Sales s LEFT JOIN Dim.Contract c ON s.Contract_BK = c.Contract_BK
    
    -- Test for missing keys
    SELECT 
        * 
    FROM 
        Fact.Sale 
    WHERE 
        Contract_SK IS NULL
    

    另一方面,我相信你的设计中有一些错误。

    • 报告期应为单独的维度。通常它是一个包含所有日期/期间相关属性的日历表。
    • 您当然不应该将ContractNbr添加到其他维度。合同维度中已经有此数据。这就是星型模式的工作原理——契约属性总是通过事实表提供给您。无需复制它们。
    • 我不能肯定(信息不足),但怀疑dim会计和dim索赔可能设计错误。如果您打算列出您的个人交易描述和个人索赔属性,那么这是一个错误。这将导致维度与事实表一样大。在一个好的设计中,事实表是“高而瘦”,而尺寸是“短而胖”。一、 在事实表中,您应该有几个字段和很多记录,而在dims中,应该有很多字段和很少记录。通常,如果dim的记录数超过事实表记录数的10-20%,则表明设计不正确。处理此问题的正确方法是将索赔分解为多个维度,并将索赔编号(订单号、发票号、交易编号等)作为“退化维度”保留在事实表中。这是一个有点高级的话题,但你显然需要它来处理你的案件。重要原因:如果你的维度和事实表一样高,你的表现会越来越差。如果传输或声明的数量在数百万条记录中,那么它可能太慢,以至于会扼杀您的设计。

    如果您需要更多信息,我推荐这本书:

    Star Schema The Complete Reference

    [编辑以回答后续问题]:

    我并不是要从索赔维度中删除ClaimNbr字段。我建议您根本不需要这样的维度。

    这可能有点难以理解,但请考虑以下几点。“索赔”本质上是一个信息容器(与“发票”、“订单”等相同)。如果您将所有有用的数据块移动到它们的相关维度,那么应该只剩下一个空容器。

    例如,假设您的OLTP索赔表包含以下字段:索赔编号、报告期、索赔描述、索赔名称、合同编号、索赔金额。可以按如下方式对其进行建模:

    • 报告期:成为“日期”维度的业务关键字
    • 合同编号:成为“合同”维度的业务密钥
    • 索赔金额:作为数字(完全相加)事实保留在事实表中

    剩下3个字段:索赔编号、索赔名称和索赔描述。此时,一些设计师创建维度“Claim”,并将这些字段停放在那里。正如我前面提到的,这是一个错误,因为这样一来,您的维度中的记录将与事实表中的记录一样多,从而导致严重的问题。

    更好的设计是将这些字段保留在事实表中。索赔编号变成了一个“退化维度”——一个“空”(不存在)维度的业务密钥。本质上,它只是一个信息容器的ID,如发票号、订单号等。

    索赔名称和索赔描述也应保留在事实表中,并成为“非数字”(非相加)事实。如果您需要在报告中显示它们,这很容易,您可以对它们进行计数,对它们进行条件逻辑,测量它们的长度,等等。

    看待这一点的另一种方式是:维度通常用于通过某些属性/字段“分割”(Disct)事实。例如,“按国家划分的销售额”、“按工厂所在地划分的产品成本”等,但你不能按描述、注释或其他自由文本划分,这毫无意义。

    如果您的描述或其他索赔属性是结构化的,该怎么办?例如,它们是否用于对您的索赔进行分类?在这种情况下,它们不是自由文本,而是属于维度的属性。例如,您可以设计维度“索赔类型”。或“索赔状态”。等等。如果这些小属性文件太多,可以将它们组合成所谓的“垃圾”维度(也称为“概要文件”维度),即维度“索赔概要文件”。这样的设计既干净又高效。

    Read more on junk dimensions here

    推荐文章