处理Datawarehouse中的空值

时间:2009-06-10 20:18:34

标签: sql ssis ssas data-warehouse

我想问一下你在输入数据仓库和SSIS / SSAS时处理空数据或空数据的最佳实践。

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

具体细节:

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

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

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

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

谢谢: - )

4 个答案:

答案 0 :(得分: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)

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

答案 1 :(得分:1)

  1. 具有适当含义的日期维度中的NULL或保留ID。记住NULL真的可以有很多不同的含义,它可能是未知的,不适用的,无效的等等。

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

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

  4. 在SSIS中,我制作了一个修剪组件,用于修剪所有琴弦末端的空格。我们通常不得不在SSIS中进行大量的日期验证和转换,这在组件中是最好的。

答案 2 :(得分:1)

感谢您的输入,

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

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

2)创建转换以检查值是否为null,如果是,则转换为-1(维度中的未知记录)或者如果它是度量值,则转换为0.表达式在下面显示为示例(I在Derived列转换中使用了这些:

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

希望将来帮助其他人; - )

答案 3 :(得分:0)

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

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

e.g。

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

和其他属性= IdOrderBirthDateOrderAmount等。

当然,如果记录的错误值(NULL)超过1个,那么你会遇到很多麻烦,但是在这种情况下,你可以扩展“跟踪”属性的数量或“返回源”并查找以及问题发生的原因(与开发部门一起)。

这有点是一个参与的步骤,但是为了完整性和正确性,我认为这是不可避免的,也是必要的,否则可能会遇到严重汇总的信息。

也许这也会帮助某人;)