II型尺寸连接

时间:2009-07-28 16:43:44

标签: sql sql-server data-warehouse dimensions type-2-dimension

我在OLTP中有以下表查找表

CREATE TABLE TransactionState
(
    TransactionStateId INT IDENTITY (1, 1) NOT NULL,
    TransactionStateName VarChar (100)
)

当这进入我的OLAP时,我按如下方式更改结构:

CREATE TABLE TransactionState
(
    TransactionStateId INT NOT NULL, /* not an IDENTITY column in OLAP */
    TransactionStateName VarChar (100) NOT NULL,
    StartDateTime DateTime NOT NULL,
    EndDateTime NULL
)

我的问题是关于TransactionStateId列。随着时间的推移,我的OLAP中可能有重复的TransactionStateId值,但是使用StartDateTime和EndDateTime的组合,它们将是唯一的。

我见过Type-2 Dimensions的样本,其中添加了OriginalTransactionStateId并且传入的TransactionStateId被映射到它,加上一个新的TransactionStateId IDENTITY字段成为PK并用于连接。

CREATE TABLE TransactionState
(
    TransactionStateId INT IDENTITY (1, 1) NOT NULL,
    OriginalTransactionStateId INT NOT NULL, /* not an IDENTITY column in OLAP */
    TransactionStateName VarChar (100) NOT NULL,
    StartDateTime DateTime NOT NULL,
    EndDateTime NULL
)

我应该使用bachellorete#2还是bachellorete#3?

3 个答案:

答案 0 :(得分:2)

通过这句话:

  

结合StartDateTimeEndDateTime,它们将是唯一的。

你的意思是他们从不重叠或者他们满足数据库UNIQUE约束?

如果是前者,那么您可以在联接中使用StartDateTime,但请注意它可能效率低,因为它会使用"<="条件而不是"="

如果是后者,则只使用假身份。

数据库通常不允许为此查询提供有效的算法:

SELECT  *
FROM    TransactionState
WHERE   @value BETWEEN StartDateTime AND EndDateTime

,除非你使用SPATIAL数据进行了晦涩的技巧。

这就是为什么你必须在JOIN

中使用这个条件
SELECT  *
FROM    factTable
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    TransactionState
        WHERE   StartDateTime <= factDateTime
        ORDER BY
                StartDateTime DESC
        )

,这将剥夺优化器使用HASH JOIN的可能性,HASH JOIN在许多情况下对此类查询最有效。

有关此方法的更多详细信息,请参阅此文章:

重写查询以便它可以使用600%导致StartDateTime次性能提升,但只有当您的日期时间具有一天或更低的准确度时(或者哈希表会变得非常大) )。

由于您的时间组件被剥离了EndDateTimeCTE,您可以像这样创建WITH cal AS ( SELECT CAST('2009-01-01' AS DATE) AS cdate UNION ALL SELECT DATEADD(day, 1, cdate) FROM cal WHERE cdate <= '2009-03-01' ), state AS ( SELECT cdate, ts.* FROM cal CROSS APPLY ( SELECT TOP 1 * FROM TransactionState WHERE StartDateTime <= cdate ORDER BY StartDateTime DESC ) ts WHERE ts.EndDateTime >= cdate ) SELECT * FROM factTable JOIN state ON cdate = DATE(factDate)

100

如果您的日期范围超过MAXRECURSION个日期,请在CTE上调整{{1}}选项。

答案 1 :(得分:1)

请注意,IDENTITY(1,1)是在该列中自动生成值的声明。这与PRIMARY KEY不同,后者是将列作为主键聚簇索引的声明。这两个声明意味着不同的东西,如果你不说PRIMARY KEY,就会产生性能影响。

答案 2 :(得分:1)

您也可以使用SSIS加载DW。在 slowly changing dimension (SCD)转换中,您可以设置如何处理每个属性。如果选择了历史属性,则将类型2 SCD应用于整行,并且转换将处理细节。如果您更喜欢start_dateend_datecurrent/expired列,也可以进行配置。

这里要区分的是主键和业务(自然)键之间的区别。主键唯一标识表中的行。业务键唯一标识业务对象/实体,并且可以在维度表中重复。每次应用SCD 2时,都会插入一个新行,并使用新的主键,但使用相同的业务键;然后将旧行标记为已过期,而将新行标记为当前 - 或者相应地填充开始日期和结束日期字段。

DW不应公开主键,因此来自OLTP的传入数据包含业务键,而主键的分配受DW控制; IDENTITY int适用于维度表中的PK。

很酷的是,SSIS中的SCD转换可以解决这个问题。