【问题标题】:Handling nulls in Datawarehouse处理数据仓库中的空值
【发布时间】:2009-06-10 20:18:34
【问题描述】:

我想请教您关于在涉及数据仓库和 SSIS/SSAS 时处理 null 或空数据值的最佳做法的意见。

我有几个在不同行中包含空值的事实和维度表。

具体说明:

1) 处理空日期/时间值的最佳方法是什么?我是否应该在我的时间或日期维度中创建一个“默认”行,并在找到空值时将 SSIS 指向默认行?

2) 处理维度数据中的空值/空值的最佳方法是什么。例如:我在“帐户”维度中有一些行在“帐户名称”列中有空(非 NULL)值。我应该将列内的这些空值或 null 值转换为特定的默认值吗?

3) 与上面的第 1 点类似 - 如果我最终得到一个 Facttable 行,但其中一个维度列中没有记录,我该怎么办?如果发生这种情况,我是否需要每个维度的默认维度记录?

4) 有关如何在 Sql server 集成服务 (SSIS) 中处理这些操作的任何建议或提示?使用的最佳数据流配置或最佳转换对象会很有帮助。

谢谢:-)

【问题讨论】:

    标签: sql ssis ssas data-warehouse


    【解决方案1】:

    正如前面的答案所述,对于一个维度,未知、不适用、未知等,Null 值可以附加许多不同的含义。如果能够在您的应用程序中添加“伪”维度条目来区分它们是有用的可以帮忙。

    在任何情况下,我都会避免使用 Null 事实外键或维度字段,即使只有一个“未知”维度值也将帮助您的用户定义包含数据质量不是 100% 的包罗万象的分组的查询(而且从来都不是)。

    我一直在使用的一个非常简单的技巧是使用 T-sql 中的 int IDENTITY(1,1) 定义我的维度代理键(从 1 开始,每行递增 1 )。伪键(“不可用”、“未分配”、“不适用”)被定义为负整数,并由在 ETL 过程开始时运行的存储过程填充。

    例如创建为

    的表
    
        CREATE TABLE [dbo].[Location]
        (
            [LocationSK] [int] IDENTITY(1,1) NOT NULL,
            [Name] [varchar](50) NOT NULL,
            [Abbreviation] [varchar](4) NOT NULL,
            [LocationBK] [int] NOT NULL,
            [EffectiveFromDate] [datetime] NOT NULL,
            [EffectiveToDate] [datetime] NULL,
            [Type1Checksum] [int] NOT NULL,
            [Type2Checksum] [int] NOT NULL,
        ) ON [PRIMARY]
    

    还有一个存储过程用

    填充表
    
    Insert Into dbo.Location (LocationSK, Name, Abbreviation, LocationBK, 
                          EffectiveFromDate,  Type1Checksum, Type2Checksum)
                Values (-1, 'Unknown location', 'Unk', -1, '1900-01-01', 0,0)
    

    我已经制定了一项规则,即每个维度至少有一个这样的伪行,用于在维度查找失败的情况下使用,并构建异常报告来跟踪分配给这些行的事实数量。

    【讨论】:

    • 有趣 - 您是否遇到过 SSAS 对负身份值的拟合问题?我知道 SSAS 讨厌我前段时间有一个 0 值作为身份。
    • 我们还没有开始使用 SSAS,我们将在几周后开始使用它。我想我们会看到的!
    • 我做了同样的事情,但我只使用了 0。我所有表的标识列都从 1 开始,所以我为几乎每个表插入了一个 0 行来表示“未知”。我发现从来不需要多个伪成员,所以我总是可以使用 0,这意味着我可以在遇到 NULL 或查找失败时在 ETL 中对其进行硬编码。当然,有时 NULL 有不同的含义,但我可以将成员的名称重命名为“None”、“Unknown”、“N/A”或任何业务需要的名称。
    • 我之前在该项目的先前实施中使用过 0,但由于 0 被用作身份密钥,SSAS 在处理多维数据集时出错。使用否定身份密钥时,我没有遇到此类错误。
    【解决方案2】:
    1. NULL 或日期维度中具有适当含义的保留 id。记住 NULL 真的可以有很多不同的含义,它可能是未知的、不适用的、无效的等等。

    2. 我更喜欢空字符串(而不是 NULLable),但在我正在处理的项目中,我现在将空字符串转换为 NULL 并允许它们在数据库中。要讨论的一个潜在问题是空白的中间声母(没有中间名,因此已知中间声母为空)与未知的中间声母或类似语义不同。为了钱,我们的模型允许 NULL - 事实上我对此有一个很大的问题,因为通常它们确实应该为 0,它们总是被用作 0,并且它们总是必须用 ISNULL() 包装。但是由于将空字符串转换为 NULL 的 ETL 策略,它们被设置为 NULL - 但这只是固定宽度传输文件格式的产物,它在某些源系统中包含空格而不是 0。

      李>
    3. 我们的事实表通常有一个基于所有维度的 PK,因此这是不允许的 - 它会链接到一个虚拟或未知维度

    4. 在 SSIS 中,我制作了一个修剪组件,用于修剪所有字符串末尾的空格。我们通常必须在 SSIS 中进行大量的日期验证和转换,这在组件中是最好的。

    【讨论】:

      【解决方案3】:

      感谢您的意见,

      我在最近的项目中做了两件事:

      1) 使用史蒂夫关于未知/特殊维度值的负 ID 键的建议。这非常有效,并且在 SSAS 多维数据集构建过程中没有出现任何问题。

      2) 创建转换来检查值是否为空,如果是,则转换为 -1(维度中的未知记录)或如果它是度量值,则转换为 0。表达式如下所示(I在派生列转换中使用这些):

      ISNULL(netWeight) ? 0 : netWeight // This is an example of a Measure column
      ISNULL(completeddateid) ? -1 : completeddateid // This is an example of a dimension key column
      

      希望这对将来的其他人有所帮助;-)

      【讨论】:

        【解决方案4】:

        我可以建议的另一个解决方案是,在ETL-step 期间,定义了一个传输表,在所有必要的转换之后将导入的记录临时存储到该传输表中。 我会在允许某人的转移表中添加一些额外的属性;在可以为 NULL 或其他不想要的值的原始值属性旁边;插入一个“编码”值,一方面标识问题和出现错误值的属性名称。

        完成后,我仍然可以决定如何在后续步骤中使用非规范化和传输的数据...可能会过滤掉错误值或在单独的错误维度中提及它们,以便包含在报告中,说明哪些值是异常的和它们如何/可能会影响聚合值。

        例如

        error-code attribute= -1 = NULL date -2 = NULL numerical value -3 = NULL PK -4 = NULL text value
        

        以及其他属性 = IdOrderBirthDateOrderAmount

        当然,如果记录可以有超过 1 个错误 (NULL) 值,那么您会遇到更多麻烦,但在这种情况下,可以扩大“跟踪”属性的数量或“返回源”并找出在哪里以及出现问题的原因(连同开发部门)

        这在某种程度上是一个复杂的步骤,但是为了完整性和正确性,我认为这是不可避免和必要的,因为否则可能会遇到严重汇总的信息。

        也许这也会对某人有所帮助;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-04
          • 2016-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-31
          相关资源
          最近更新 更多