避免“裂缝陷阱”(数据建模-USS)

有的业务需求需要联合使用多张事实表才能实现,这时通常会出现直接或间接多对多的连接情况,而多对多是必然会出现数据发散现象的。下面以 UserSkills、UserLanguages 以及 Users 三张表来演示间接的多对多情况:

chasm_trap_03

假如有业务需求:①从会Python的员工中找出English最好的那个;②所有会Python的员工的平均English评分多少。这两个需求都同时涉及到两张表的数据,直接对两张表进行连接会出现度量数据的发散,再进行聚合很容易得到错误的数据结果(尤其是第二个需求):

chasm_trap_02
chasm_trap_04

对于记录数分别为 m 和 n 的两张多对多关系的表,连接后的结果表记录数会在min(m,n)m*n之间;三张表同理可知在min(n1,n2,n3)n1*n2*n3之间。

有经验的技术人员可能会采用SQL的EXISTS语句这种过滤手段(或叫半连接,semi-join)来避免连接的发散问题,从而可以得到正确的数据结果,比如第二个需求的SQL代码:

SELECT UserLanguages.User
       ,Users.UserName
       ,AVG(UserLanguages.LangRating) as avg_english_rating
FROM UserLanguages
     LEFT JOIN Users
            ON UserLanguages.User = Users.User
WHERE UserLanguages.Language = 'English'
      AND EXISTS(SELECT 1
                 FROM UserSkills
                 WHERE Skill = 'Python' AND User = UserLanguages.User)
GROUP BY UserLanguages.User
         Users.UserName;

USS 的解决方案

统一星型模式(USS)则完全不存在多对多的数据发散问题,因为其桥接表中只存在一对一和多对一的连接方式,以及UNION ALL的拼接方式,而UNION ALL也是天生对发散免疫。下面用连接的方式来演示 USS 的解决方案:

当然,最佳的方案永远是 USS 方案与具备关联(association)的BI工具的组合使用。(另见〖避免“风扇陷阱”(USS)〗)

chasm_trap_05

现在来演示同样第二个需求的解决办法:在BI工具(这里以FineBI为例)中将桥接表(Bridge)与三张表连接得到上图的大宽表后,分析人员可在FineBI中创建如下组件:

chasm_trap_06

值得一提的是,若数据模型采用关联的方式,(此例的)其组件写法也是一模一样的。

这样就成功得到了正确的计算结果,其中唯一的难点是添加人工计算字段“Python_flag”,然而也相比传统的SQL代码简单很多。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值