如何获取传入事实记录的精确代理键
Posted
技术标签:
【中文标题】如何获取传入事实记录的精确代理键【英文标题】:How to get the precise surrogate key for the incomming fact records 【发布时间】:2019-10-31 11:20:15 【问题描述】:我正在为我的公司建立一个数据仓库。最近,我才意识到我的 SCD 类型 2 维实现中存在一些漏洞(可能非常危险),因此我必须重新审视它。
SCD 类型 2 维表的当前“fromdate”是它进入数据仓库的日期,或者它替换旧记录的日期,“todate”通常为空,或者是新记录的日期用相同的自然键替换旧记录。
目前,在加载事实时,我通过使用自然键和条件 iscurrent = true 或 todate = null 来获取该事实的代理键。
我只是意识到这并不能保证代理键的正确性,例如:
如果更改发生在上午 11:00。这意味着:当天发生的交易有一半与旧维度记录相关,一半与新维度记录相关。但是当数据来到数仓时,当天的所有交易都会被视为与新维度相关,这是不正确的。
如果我们使用事务的日期时间来更精确地获取代理键,当将事实记录加载到数据仓库时,维度到达数据仓库之前发生的所有事务将无法找到与之相关的任何维度代理键。例如:我昨天制作了维度表,因此该 SCD 2 维度表中的所有开始日期的最小值都为昨天,而几乎所有旧事务(尚未加载到数据仓库)都发生在之前那天。所以他们将没有代理键。这样的悖论。
我什至尝试通过在 OLTP 系统中传递该维度行的创建日期来合并行的开始日期以使其更精确。但是我仍然找不到最正确的方法。首先Data Warehouse和OLTP系统中的日期时间不同(因为它们可能属于不同的GMT+X)...
还有很多其他问题.....
我知道,如果我们想以非常精确的精度跟踪历史记录,唯一的方法是我们必须在 OLTP 系统中通过直接将相关实体写入事务记录来实现它。数据仓库做不到。但是我还是觉得SCD 2的概念漏洞太多,或者说我没有正确实现SCD Typ2 2系统。所以请教我以上问题是否正常,或者指出我理解中的错误。
【问题讨论】:
【参考方案1】:如果时间很重要,请使用datetime
而不是date
。但首先要考虑时间是否重要
再次使用datetime
解决
确定您的数据仓库所在的时区。
UTC 源系统 本地系统 时区感知数据类型请注意:我建议您使用 2099-01-01 而不是 NULL 作为当前记录的结束日期。然后您可以在搜索匹配的维度成员时轻松使用between
。
-
您需要更加具体
编辑:
迄今为止基于cmets的一个观察:不要使用Is_Current
查找代理键,使用事务中的业务键和事务日期时间在维度开始和结束日期。
这意味着您可以重新加载三个月前的数据,它会选择正确的维度成员(不是当前的)
这强化了我的另一条评论,即不使用 NULL 作为活动记录结束日期。而是使用日期时间方式进入未来。所以你总是可以在这些日期之间得到结果
【讨论】:
日期或日期时间无关紧要。因为维度表中新行的开始日期取决于数据仓库,而事务的日期取决于OLTP系统。 EG:如果数据仓库的同步间隔是2天,那么新维度行的开始日期是第2天,但实际上它是在第1天创建的,并且已经发生了很多与之相关的事务在第 1 天。因此,如果您使用交易时间进行跟踪,则第 1 天的所有交易都会丢失它的维度。如果你使用current,一半的交易会出错。 首先:不要使用 is_current 来查找代理键。在您正在加载的事务中使用业务密钥,以及事务在 SCD 开始日期和结束日期之间的日期时间。这意味着您可以随时加载事务,它会选择正确的代理键。 其次:除非您拥有维度成员在源系统中“生效”的“真实”日期时间,否则您无能为力。如果您每五天阅读一次源系统,并且源系统中没有指示维度(例如:位置)何时变为活动状态,那么您无能为力。更糟糕的是,如果记录在这五天内更改了两次,而您完全错过了第一次更改。 所以您的意思是我应该使用 OLTP 系统中该行的创建日期/更新日期来填充 SCD 类型 2 表的 startdate 列,对吗?如果我无法获得这些信息,我应该放弃制作 SCD 2 型表吧?问题是我读过的 Kimball 小组的指南建议我使用该行到达我们 DW 的日期。 (设计技巧 107 - convert(char(10), getdate()-1, 101),即使是 SSIS 的 SCD 类型 2 函数也使用这个日期来制作 SCD 类型 2 表。但是这种方法永远无法达到真正的正确性,因为数据仓库的同步间隔。 不要放弃。只需认识到这个问题并将其作为风险与利益相关者进行沟通。我强烈建议您不要使用 SSIS SCD 组件。以上是关于如何获取传入事实记录的精确代理键的主要内容,如果未能解决你的问题,请参考以下文章
Android的Service如何获取Activity传入的值
如何在 Linux tclsh 中通过光标键获取命令历史记录