7

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

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

规格:

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

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

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

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

谢谢 :-)

4

4 回答 4

4

正如前面的答案所述,一个维度的 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)

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

于 2009-06-11T20:21:10.480 回答
1
  1. NULL 或您的日期维度中具有适当含义的保留 id。记住 NULL 真的可以有很多不同的含义,它可能是未知的、不适用的、无效的等等。

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

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

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

于 2009-06-10T21:50:45.683 回答
1

感谢您的输入,

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

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

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

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

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

于 2009-06-12T18:23:22.720 回答
0

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

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

例如

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

和另一个属性 = IdOrder, BirthDate, OrderAmount, 等等。

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

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

也许这也会帮助某人;)

于 2011-08-31T13:50:28.637 回答