2.3.4 解决不明确的Relationships
当查询主题或维度表达的数据可以在多个上下文或角色中查看或以多种方式联接时,会产生不明确的关系。最常见的不明确关系是:
2.3.4.1 角色扮演维度
自身与其它表之间有多重有效关系的表称为角色扮演维度。如下图
事实表Sales fact描述产品销售信息,其中包括‘订单日期’、‘出口日期’与‘订单结束日期’,那么维表 Time存在3个日期关联。若像图中所示建立关联,在实际查询中会形成如下SQL语句:
Select * from Sales_fact a,Time b
Where a.Daykey(order date)=b.Daykey
and a.Daykey(ship date)=b.Daykey
and a.Daykey(close date)=b.Daykey
如此一来,当客户任意查询其中某个信息时,FM就默认必须满足Where子句后面的3个条件,因此不符合业务逻辑需求。
如何解决?必须删除导入对象、资料查询主题和角色扮演维度查询主题的关系。为每个角色创建一个模型查询主题。考虑排除不需要的查询项目以减小显示给用户的元数据树的长度。确保每个模型查询主题与资料查询主题之间只存在一个恰当的关系。
基于模型中存在的Time维表新建3个查询对象,分别为OrderDay,ShipDay 和CloseDay
当客户查询某个出口日期期间的销售情况,则会按照以下规则生产独立的SQL代码:
Select * from Sales_fact a,Ship_Day b Where a.Day_Key(ship date)=b.Daykey
注意事项:
若即要查询某个订单日期的销售产品信息,又要查询 Forecast Sales计划销售情况,就会涉及到多资料查询。
我们可以如下设置关系:
您可以将“Ship Day”、“Order Day”和“Close Day”视为可与“Product forecast”资料互换的时间查询主题。在查询“Product forecast”资料时,一次仅能使用一个时间维度,否则您的报表可能不包含任何数据。例如,Month_key=Ship Month Key (200401) 和Month key=Close Month Key(200312)。
2.3.4.2 循环联接
循环连接,从字面含义很容易理解,类似于一个电路回路。模型中的循环联接通常会导致许多不可预测的行为。这并不包含星形模式循环联接。如果出现循环联接,则问题的主要标志是定义不明确的查询主题。当查询主题定义不明确并成为循环联接的一部分时,将基于多种因素(例如关系的位置、联接路径中的分段数)确定给定查询中使用的联接;如果其它条件均平等,则首先按照字母顺序联接路径。这会使您的用户感到困惑,因此我们建议您进行建模以明确标识联接路径。如下图所示,我们可以有2个查询订单order的方法
方法1、将“Branch”直接联接至“Order”
方法2、通过“Sales Staff”联接至“Order”;
主要问题是这俩路径获取的结果不同。因为员工可在销售处之间移动,所以尽管该年内移动的员工完成的许多销售归于其以前的销售处,但他们会累积至当前的销售处。由于这是建模方式,因此不能保证将选择哪条联接路径,可能会根据查询中选择的项目而改变。
这个问题的唯一解决方法是,根据实际查询需求而定义查询。若需查询某部门当前员工的销售订单,者用方法2;若需查询某部门累计的销售订单信息则用方法1。为了避免给报表人员造成迷惑,我们新建shortcut to Branch再与Order建立关系。
2.3.4.3 反身关系和递归关系
反身或递归关系,我们实际使用时经常使用到,如组织机构(Depart_id,Parent_id,Depart_Name,Dept_Level),Depart_id和Parent_id就是如此。反身关系和递归关系暗示了两种或多种粒度级别。Framework Manager 导入反身关系,但在执行查询时并不使用它们。如下图中显示反身关系(自联接)仅出于表达目的。
“Sales Staff”查询主题在“Staff Code”和“Manager Code”之间存在递归关系(这点水晶报表中处理得很好,它自带了一个‘层级分组’的功能)。为创建功能性反身关系,可以创建别名快捷方式(数据源查询主题的副本)或模型查询主题。然后在原始查询主题和新的查询主题之间创建关系。从维护角度来看,快捷方式是更好的解决方案。
基于Salse Staff建立查询主题 Manager ,然后建立关联,如下图:
但是这样只能解决一个层级问题,若部门机构有3个层次,那该如何办?那我们就建立3个基于sales staff的查询主题,如 1st Manager、2nd Manager、3rd Manager,然后建立关联,如下示意图:1st Manager: select * from Sales Staff where level=1…依次类推(根据您实际表的特征来区分是1st Manger还是2nd Manager)。
解决不明关系,其实就是一个根据实际需求来简化模型的过程。另外还有一个概念是‘关系陷阱’,两者有什么区别呢?若说‘不明关系’给模型使用者造成迷惑、甚至查询数据不准确,‘关系陷阱’则会造成复杂甚至是错误的建模,问题相对更为严重。那么如何解决呢?请关注下一篇 ‘2.3.5 关系陷阱的认识与解决方法’。