一般来说,是不需要环状模型的,环状模型通常都可以通过别名等方式转换成非环状的(BIEE 10g在逻辑层是不允许建立环状模型的(物理层可以),而11g 则没有了这个限制)
但是某种情况下,还真需要环状模型。
考虑如下简单模型
可以看到,上图中的产品维采用了Type2 的缓慢变化维;因此其含有开始时间和结束时间字段为于标识对应记录的有效时间段。
考虑如下需求,一个仪表盘提示有两个字段,分别是“CALENDAR_YEAR”(Dim_Date)、“PROD_DESC”(Dim_Products);客户要求当我选定了“年”之后,“产品描述”里
只能出现对应年的“产品描述”,拿同一个产品为例,比如:
年 产品编码 产品描述
1998 TP_123 产品A_OLD
1999 TP_123 产品A_NEW
当我选了1999年之后只能出现产品A_NEW,而不要出现产品A_OLD
新手拿到这个问题都会觉得很“简单”,只要PROD_DESC的值受CALENDAR_YEAR限制即可,如下图所示:
OK,大功告成!测试测试,
选择好CALENDAR_YEAR,然后在选择PROD_DESC。
1分钟、2分钟.....
10分钟过去了怎么PROD_DESC还出不来!
这是很多新手经常会遇到的一个问题,为什么会这样?
很简单,因为在维度模型中,维表与维表的关联关系都存在于事实表之中,想要用一个维度的值去限定另一个维度的值必然要连接事实表,
所以在提示中用一个维度去限制另一个维度肯定会有性能问题(当然了,事实表数据量小性能会在可接受范围内)
那么我们应该怎么来处理这种问题呢?
实际上这种问题从根本上是因为产品维和时间维并非毫无关联,而是存在着一定的联系(因为某条产品记录只在某个时间段内有效)
这个时候我们可以引入一个支架时间维,将它与产品维连接起来,如下图所示:
其中Dim_Date_Products_LifeCycle和Dim_Date都是真实物理表TIMES的别名(使用别名,是我们在BIEE中实现角色扮演维的常用手段)
这样的话,我们能可以很方便的使用Dim_Date_Products_LifeCycle来对Dim_Products进行筛选了(前端只需要使用等于Dim_Date_Products_LifeCycle上的某个时间点,而不用去写复杂的>=开始时间 and <结束时间这样的逻辑了)
接下来又有一个问题,我们是把这个支架维放在逻辑层的产品维度里呢,还是放在时间维度里呢?
如果放在产品维度里把其当成产品上的一个属性是说得过去的,但是这样的话又回到我们在做提示的时候还是会遇到前面所说的问题。
我们需要的是把这个支架时间维和真正的时间维合2为一,也就是说,当我们指定了时间(通过时间维的字段),这个值需要自动传递到支架维上
然后支架维去关联产品维以取出对应时间段的产品描述(而无须关联事实表)
How can we do?
一步一步的来吧,合2为一我们肯定就会想到利用逻辑层的多LTS(Logic Table Source),如下图所示:
注意:不要修改Dim_Date中,两个LBS的“优先级组”,让它们都默认为0
我们希望的是,如果我在answer里只选择时间和产品两个字段,那么BI Server就选择Dim_Date的Dim_Date_Products_LifeCycle去关联Dim_Products表(它们有直接关联)而不要选择
Dim_Date(因为一旦选择了它,则必然会关联事实表,因为Dim_Date和Dim_Products是没有直接关联的)
而当我们同时指定了时间、产品以及指标的时候,我们希望的是BI Server选择Dim_date和Dim_Products与事实表关联
通过测试,目前这样并不能达到我们的要求,BI Server始终都要去关联事实表,为什么?
大家仔细看目前的逻辑模型图,只看逻辑模型的话,BI Server所得知的Dim_Products和Dim_Date之间是没有直接关联路径的(虽然它们的LBS在物理层有),
我们需要把这种关联关系告诉给BI Server,也就是如下图所示:
注:如果没记错,逻辑环状模型在BIEE 10g中是不支持的
这要就行成了一个环状的模型!当我们只选择Dim_Date和Dim_Products的时候,BI Server就会走路径1;
当选择Dim_Date、Dim_Products、Fact_Sales的时候,BI Server就会走路径2
OK,下面让我们看一下测试结果吧!
新建如下图的提示:
其中PROD_DESC的取值受CALENDAR_YEAR限制,当我们选定好年之后,我们就只能在PROD_DESC中选择对应年的成员值了,SQL如下:
select distinct T195345.PROD_DESC as c1 from TIMES T195762 /* Dim_Date_Products_LifeCycle */ , PRODUCTS T195345 /* Dim_Products */ where ( T195762.CALENDAR_YEAR = 1999 and T195762.TIME_ID < T195345.PROD_EFF_TO and T195762.TIME_ID >= T195345.PROD_EFF_FROM ) order by c1
如我们所愿,没有关联事实表
下面我们在看看两都同时指定,并有指标的情况下,会按我们所希望的那样吗
WITH SAWITH0 AS (select sum(T195337.AMOUNT_SOLD) as c1, T195298.CALENDAR_YEAR as c2, T195345.PROD_DESC as c3 from TIMES T195298 /* Dim_Date */ , PRODUCTS T195345 /* Dim_Products */ , SALES T195337 /* Fact_Sales */ where ( T195298.CALENDAR_YEAR = 1999 and T195298.TIME_ID = T195337.TIME_ID and T195337.PROD_ID = T195345.PROD_ID and T195345.PROD_DESC = '3DVD-R Discs, 4.7GB, Pack of 5' ) group by T195298.CALENDAR_YEAR, T195345.PROD_DESC) select distinct 0 as c1, D1.c2 as c2, D1.c3 as c3, D1.c1 as c4 from SAWITH0 D1 order by c2, c3
可以看到,此时走的是路径2,也就是我们所希望的那样。
完!