2.3.5 关系陷阱的认识与解决方案
进行复杂的关系建模时候,往往会有多个查询对象,而查询对象之间又存在一个或多个relationships,它能把单个查询对象联合起来,从而报表进行多表查询时无须report author再指定表之间的关系。但报表 report author 开发报表时候并不能再Studio里看到查询对象之间建模的relationships图,若查询对象之间有不明确的或错误的关联,则会造成报表查询结果错误。Report author在不知情的情况下(无开发逻辑错误情况下),生成了错误的报表,我们称之为 关系陷阱。
关系陷阱总的来说分4种:转移陷阱、连接陷阱、深坑陷阱和扇形陷阱。
2.3.5.1 转移陷阱
和上一章节 “2.3.4 FM不明确的Relationships” 中的循环链接一样。若两个查询主题之间存在多个路径,就存在转移。如下图所示,从业务的角度看这两条路径所查询的结果会有差异。
在此示例中,可以有2条路径:
① 、“Branch”直接联接至“Order”
② 、通过“Sales Staff”联接至“Order”。
主要问题是 路径①和 路径②获取的结果不同。这是因为员工可在销售部门之间移动,所以尽管该年内移动的员工在以前的销售处完成了许多销售业绩,但他们会累积至当前的销售处。由于这是建模方式,因此不能保证将选择哪条联接路径,可能会根据查询中选择的项目而改变。
解决方案如下:
1、为查询对象Branch创建 Alias Shortcut(别名快捷),新的查询对象ShortCut to Branch和源查询对象 Branch彼此独立。为shortcut to Branch与Order新建新的relationship,如下图:
2、查询某部门的实际总体业绩,用路径①;
查询部门中某员工的总体业绩,用路径②
然后组织模型,如下图右边,Report Author便可看到明确模型主题
2.3.5.2 连接陷阱
连接陷阱是一个通过不同实体的可选路径。如,公司、部门、员工之间是3级层关系
Report Author开发报表时,能直接看出Branch和Depart有同名字段Branch_ID关联、Depart和SalesStaff有同名字段Dep_id关联。从业务角度考虑,Branch和Depart肯定是有直接关系的,而模型中查询主题中,两者并没有直接可靠的关联字段。有些企业在全国各地有很多分公司、多个部门,公司制度是通过总部部门直属管理,而非分公司。因此,我们就会问“SalesStaff和Enterprise是从属关系么?”(如张三属于微软研发部门人员,从模型中,你就无法根据他所在的部门查找出他所在的分公司)
解决方案如下:将Branch和Depart合并
2.3.5.3 深坑陷阱
多对多关系称之为深坑陷阱,这种结构不能记录数据和维护数据,可以让一个信息陷入深坑。然而在高层次上并不是错误的,只是查询不出所有的必要细节。如下图所示:
解决方案如下:
①简化为1..n模式:
指定特定的供应商或零件,既然一个零件可以是多个供应商提供,那么我们可以查询某一个特定的零件是由哪些供应商提供。
Select * from customer a,retails_product b
where b.product_code=’991’ //指定特定零件,再关联
and b.customer_id=a.customer_id
②找出共同查询主题:供应商要提供零件,通常都需要有订单。将查询主题 Order引入其中,如下:
某个供应商通过订单查找相关的零件。
2.3.5.4 扇形陷阱
一个查询主题展开的多个一对多关系,就是扇形。
如果向图中建模发布到Cognos Connection中,Report Author开发报表时仅能看到三个查询主题:
Branch LTD
Depart
Staff
开发者误以为Depart 和Staff有业务关联,将Depart_name、Staff_name拖入报表对象中查询数据,可想而知会得到什么结果。
解决方案如下:
假如Depart 和Staff确实存在业务关联,那么该如何建立关联呢,这个问题留给感兴趣的朋友去研究。
一般而言,我们平时建模设计时不会涉及今天所讲到的内容,因为关系陷阱只在进行较复杂的关系建模时发生。通过今天粗略的讲解,我想有些朋友会对关系陷阱有所认识,以后建模设计时候也会习惯性的考虑如何避免陷阱的问题。教程系列至此,Relationships方面的内容就讲完了,下一章将给大家讲解 “2.3.6 三种不同类型的Query Subjects”。(最近一段时间经常出差,耽误了教程的更新进度,希望大家理解并指出不足之处,多谢!)