我们通常在数据仓库的设计中碰到这种问题:在维度设计中如果这个维度只有一个属性,那我们面临的选择是为这个属性单独创建一个维度,还是将这个维度的属性直接放在事实表中作为事实表的一部分?
假设这里有一个维度,通常在设计上至少会有两列(DimKey 和 DimAttribute 属性),事实表通过 DimKey 关联到这个维度。首先,在查询阶段多表的 JOIN 关系比较单表的查询在效率上肯定要低一些,我们来看下下面的这个例子:
CREATE DIM_TABLE
(
DIM_KEY INT PRIMARY KEY IDENTITY(1,1),
DIM_ATTR NVARCHAR(20)
)
CREATE FACT_TABLE
(
DIM_KEY INT FOREIGN KEY REFERENCES DIM_TABLE(DIM_KEY),
MEASURE DECIMAL(18,2)
)
一个典型的星型结构的查询如下:
SELECT D.DIM_ATTR,
SUM(F.MEASURE) AS TOTAL
FROM FACT_TABLE AS F
INNER JOIN DIM_TABLE AS D
ON F.DIM_KEY = D.DIM_KEY
GROUP BY D.DIM_ATTR
如果把这个属性直接放在 FACT 表中,结果和查询如下:
CREATE TABLE FACT_TABLE_2
(
DIM_ATTR INT FOREIGN KEY REFERENCES DIM_TABLE(DIM_KEY),
MEASURE DECIMAL(18,2)
)
SELECT SUM(MEASURE) AS TOTAL
FROM FACT_TABLE_2
GROUP BY DIM_ATTR
我们的查询和聚合更加简单,从查询效率上来说要更好一些。但是我们通常又为什么会选择将这个单独的属性还是放在维度表中,这里有以下几个原因是我们需要考虑的:
1. 如果事实表非常庞大的话,使用 DIM_KEY INT 类型 4 Bytes 相对于 DIM_ATTR 的 NVARCHAR(20) 类型可以明显的减少事实表的体积。
2. 如果这个属性值在源业务系统发生改变的话,就意味着我们要更新事实表中所有与该属性相关的属性值。
3. 有可能今天这个维度确实只有一个属性,但是谁又能确保这个维度以后不会添加别的相关的属性呢?
数据仓库的设计是一个迭代的开发过程,开发一年,维护若干年,如果我们可以考虑到以上原因,就可以很清楚的考虑到在设计阶段是否有必要将单一属性挑选出来作为维度来设计了。