数据仓库中使用代理键(Surrogate Key)

            在DW开发中,常常会使用到代理键,很多做了很多年的DWer对于何时使用代理键,使用代理键的优劣势是什么,已然很模糊。首先我们看看对于代理键的定义,这里引用wiki上对于代理键的两个定义:

 

Surrogate (1) – Hall, Owlett and Codd (1976)A surrogate represents an   entity  in the outside world. The surrogate is internally generated by the system but is nevertheless visible to the user or application.  Surrogate (2) – Wieringa and De Jonge (1991)A surrogate represents an   object  in the database itself. The surrogate is internally generated by the system and is invisible to the user or application.

 

在数据库层面,Oracle中的rowid可以视为第二种定义的实现,这篇文章里面我想谈谈第一个种定义下的代理键。

 

做过DW的人,当问起最常用的代理键使用场景的时候,往往会提到缓慢变化维。当然这是最常见到使用代理键的情况。

 

如下图,当供应商A的地址从一个城市搬到另外一个城市,那么通过系统自动生成代理键。(很多DW系统里面增加生效时间段或是启用状态标志位作为区分)

数据仓库中使用代理键(Surrogate Key)_第1张图片

 

其他情况下,维度表是否需要采用代理键?

我认为在多业务源的EDW系统中,有一种情况下是需要的。

如果在企业的主数据管理系统中,对于某项业务主数据的定义尚未建立(或不完善)。如业务系统A与业务系统B的某商品的商品编码有不一致的情况,即使不是作为缓慢变化维,这里仍应该生成不同的代理键,以做区分。否则,事实表与维表的关联查询时,比如业务用户用商品名称进行查询,而不是商品编码的情况下,在查询过程中可能出现一对多的联接 ,造成数据假象。这种情况非常常见,特别是很多legacy系统中,由于年代较久远,数据与当下数据定义不一致的情况,较常出现 。

 

事实表是否需要加代理键?

这个问题,确实很有意思。从业务的角度上说,完全没必要,因为事实表的业务主键完全可以定义记录的唯一性。从Best  practice的角度说,我觉得在一些可预见的、需要在未来做主键拓展、数据量巨大的事实表上,还是需要加代理键的。

举个实际的场景,公司现在有一张订单表,目前使用的主键订单号、门店号、商品号 、销售时间,由于业务系统改造,现在除了订单号,还能提供订单上的条目号。由于订单数据量巨大,先将原表中记录里的空字段置为非空值,再加主键的做法,简直是一个灾难。如果当初在设计该表时,使用代理键作为主键的话,这个问题就不存在了。解决的方法,只有drop掉业务主键,增加唯一索引。

事实表需不需要加代理主键,从Best practic的角度来说,答案是趋向肯定的。而加代理键的前提,是需要模型师仔细斟酌的。因为这还需要增加额外索引开销,毕竟对于日益庞大的EDW系统,怎么进行瘦身,也是模型师需要考虑的问题之一。

 

你可能感兴趣的:(数据建模)