• 本站分享从数据采集到数据应用全链条知识,包含数据仓库搭建、数据分析、模型算法、数据平台系统、数据产品等。
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

有赞BI平台实现原理

全部文章 hey 5年前 (2020-11-27) 596次浏览 0个评论 扫描二维码


有赞BI平台实现原理

作者:蒋羽中 & 张俊英

部门:数据中台

一、概述

1.1 背景

有赞是一家 SaaS 公司,更是一家大数据公司。如何从海量数据中高效地挖掘数据的价值,并对数据进行可视化分析与展示,是我们亟待解决的问题。鉴于此有赞BI 平台应运而生,BI 平台经过多次迭代,使用户可以快速方便地在 BI 平台进行数据的分析与展示,满足了不同业务的取数需求,目前月均 UV 700+,PV 3W5+,报表总数 5K+。

本文主要从以下三方面进行阐述:

1.2 面向用户及应用场景

BI 平台面向的用户主要包括:

具体的应用场景以及分析如图 1.1 所示:

有赞BI平台实现原理

图 1.1 BI 平台应用场景举例

二、可视化分析数据

2.1 术语简介

有赞BI平台实现原理
图 1.2 维度类型
 

2.2 快速入门

在 BI 平台,只需要三步便可完成数据的可视化分析
有赞BI平台实现原理
图 1.3 可视化分析步骤
 

step1: 添加数据集

操作路径:添加数据集->选择连接账户->自定义 SQL->预览数据->提交。
有赞BI平台实现原理
图 1.4 添加数据集
这里的数据集是一段逻辑 SQL,相当于后续图表取数的 table。
小技巧 1.可在字段的右上角齿轮处标记字段的日期类型及格式,当标记为日期类型时,可使用日期的时间粒度,时间组件等。

step2: 添加报表

操作路径:新建图表->选择刚刚建的数据集->确认,即可进入报表编辑页。

有赞BI平台实现原理

图 1.5 图表编辑
小技巧   1.添加计算字段:适合需要二次加工计算的指标如转化率 = count(XXX) / count(XXX)(相当于Excel pivot 里的计算字段)2.报表复制功能场景:已有报表"top GMV 的营销活动", 需要添加 "top 买家数的营销活动"此时便可使用报表的复制功能

step3: 添加权限

操作路径:进入看板->点击右上角齿轮->添加权限。或者可在”资源管理”处管理权限。
有赞BI平台实现原理
图 1.6 权限管理
此步骤是为了保障数据的安全性,只有有相应权限的用户可进行相关的操作。

2.3 图表类型

目前 BI 平台已经支持超过 10 种的图表类型,涵盖日常数据可视化分析的绝大部分场景需求,示例如图 1.7、1.8、1.9 所示。不同类型的图表适用于不同的使用场景,展开来讲:
有赞BI平台实现原理

图 1.7 图表类型-1

 有赞BI平台实现原理

图 1.8 图表类型-2

有赞BI平台实现原理

图 1.9 图表类型-3

2.4 筛选与排序

制作图表时可按需筛选用户所关注的数据,也可从不同的时间维度观察数据,支持按某种排序规则对指标排序,方便用户快速从数据中获取信息。
有赞BI平台实现原理
图 2.0 日期类型及格式

2.5 计算字段

对需要二次加工计算的指标,如转化率等,用户可自定义 SQL 片段对数据集进行加工,生成额外的虚拟字段。支持报表级别、数据集级别的计算字段,报表级别的计算字段只能归本报表使用,当定义数据集级别的计算字段时,使用该数据集的报表均可使用此计算字段。

2.6 下钻与联动

下钻是在粗粒度的报表数据上,需要查看更细粒度的数据的背景下产生的,旨在解决业务上查看比当前数据更细粒度数据的需求,与数仓概念中的“下钻”同义,如对“各省份的付费商家数据”,查看“某省份市级别的付费商家数据”。

有赞BI平台实现原理

图 2.1 下钻图(查看省市级别的统计数据)
支持对同数据集多个报表或不同数据集多个报表的下钻,同数据集多个报表的隔层的父图层条件会自动作用于当前图层,如 a->b->c,a 层的条件会作用于 c 层;不同数据集多个报表隔层的父图层条件需要用户配置是否作用于当前图层。
联动是指多个报表之间的关系,当一个报表条件改变时,被联动的报表数据随之变动,如图 2.2。

有赞BI平台实现原理

图 2.2 联动图-1

当点击“新付费商家数-by 城市等级图“的“一线城市”时,结果如下 :
有赞BI平台实现原理

图 2.3 联动图-2

2.7 行列权限

对同个报表,不同的人看到的数据或字段信息应该是不一样的,如杭州地区的销售经理只能看到杭州地区的销售情况,上海地区的销售经理只能看到上海地区的销售情况,但销售总监可以看到各个地区的销售情况。这种背景下,数据集上的行列权限便可大展身手了。

有赞BI平台实现原理

图 2.4 行列权限-条件模式

有赞BI平台实现原理

图 2.5 行列权限-自由模式

自由模式通过写 SQL 来设置条件,目前按用户的基础属性开放可设置的字段,后续支持不同业务上自定义的条件,e.g.[dep] in {db.table.businessId.value}。多个条件间为 OR 关系,由此实现了对不同的人或组的数据过滤功能,保证了字段级别的数据安全。

2.8 图表推送
为方便用户对数据的及时了解,用户无需登录 BI 平台查看报表,只需要在 BI 平台上配置推送的信息,如何时推送,以什么形式推送等,收件人便可以在配置的时间点收到报表数据的推送,提升用户对数据的感知度。
2.9 外部应用集成
对有数据可视化分析与展示需求的外部产品,都可以利用 BI 的分析处理工具定制图表,通过 BI 平台提供的 SDK 快速嵌入 BI 看板、报表和 BI 平台的分析组件,并可以自定义传参实现灵活的图表展示,提升各产品制作图表的效率。
2.10 移动端

有赞BI 可以在移动端查看报表,支持与图表进行简单的交互,如筛选、下钻、联动等。支持 Android 和 IOS 系统,用户可以随时随地查看报表。

三、实现原理

有赞BI 平台的搭建涉及到了许许多多的技术和组件,如何将用户在前端对数据集字段的拖拽翻译成 SQL 并查询数据是比较重要的一个部分,下面将简要介绍一下实现方式。
3.1 行维度、数值、筛选、排序与分页
有赞BI平台实现原理

图 2.6 demo

上图拖拽的语义为:根据“订单类型”的不同取值,统计“买家数量”和“成交金额”,其中统计的订单需要满足其日期符合筛选条件(日期按年计算,只统计今年的订单),对结果集按“成交金额”升序排列,并对结果集做分页处理。拖拽完成后最终生成的 SQL 为:

SELECT *FROM (  SELECT *, row_number() OVER () AS bi_rownum  FROM (    SELECT order_type AS bi_rowdim0, COUNT(buyer_id) AS bi_metric0, SUM(gmv) AS bi_metric1    FROM (      SELECT *      FROM dm_zbk.da_self_analysis_demo    ) mid_dataset    WHERE the_date >= '2020-01-01'      AND the_date <= '2020-12-31'    GROUP BY order_type    ORDER BY bi_metric1 ASC  ))WHERE bi_rownum > 0  AND bi_rownum <= 10

从中可以看出,行维度对应 SQL 中的 group by 部分,数值对应 SQL 中的聚合函数部分,筛选对应 SQL 中的 where 部分,排序对应 SQL 中的 order by 部分。而分页根据不同的数据库连接,会有不同出的处理方式,例如 mysql 中对应 limit,在 presto 中需要自己使用 row_number over 函数自行处理。

3.2 列维度

类似于行维度,列维度也是维度的一种形式,相当于 excel 表格中的数值列上方的多行表头。

有赞BI平台实现原理

图 2.8 行维

 

有赞BI平台实现原理

图 2.9 列维
要分析某个维度下的数值,既可以将维度放在行维度上,也可以将维度放在列维度上。如上图将“订单类型”维度放在列维度上,对比将“订单类型”维度放在行维度上,可以发现数据是一致的,只是将行数据转置到了列上。对于列维度的 SQL 实现,可能会有许多种实现方式。如可以类似行维度的处理,将列维度也作为 group by 的部分,然后通过代码组装数据到列上;也可以直接使用部分数据库提供的 pivot 函数,又或者直接在 select 数值部分的时候拆分成多列查询等。三种方式对比如下: 

有赞BI平台实现原理

图 3.0 列维 SQL 三种方式对比
有赞BI 平台使用的是最后一种方法。 上图查询对应的 SQL 为:
    SELECT SUM(if(order_type = '订单类型 1', gmv, 0)) AS bi_metric0      , SUM(if(order_type = '订单类型 2', gmv, 0)) AS bi_metric1      , SUM(if(order_type = '订单类型 3', gmv, 0)) AS bi_metric2      , SUM(if(order_type = '订单类型 4', gmv, 0)) AS bi_metric3    FROM (      SELECT *      FROM dm_zbk.da_self_analysis_demo    ) mid_dataset
可以看到原本 sum(gmv)因为“订单类型”的多种不同取值的原因分割成了多个 select if 语句。对于有列维度的情况,会先执行一次 select distinct 列维度的操作,获取列维度的唯一值以后再次拼接真正查询数据的 SQL。当列数量过多的时候也可以进行横向的分页,即 select distinct 列维度取唯一值的时候做分页。列维度中“度量名”虚拟字段代表的是数值与列维度的排序关系,会影响表头的顺序。

有赞BI平台实现原理

图 3.1 度量名位于下方的数据

有赞BI平台实现原理

图 3.2 度量名位于上方的数据
这是通过控制 select if 语句的顺序实现的,对比 2 个图的 SQL 结构便可知。
订单类型在度量名上时的 SQL 如下:
    SELECT COUNT(if(order_type = '订单类型 1', buyer_id, NULL)) AS bi_metric0      , SUM(if(order_type = '订单类型 1', gmv, 0)) AS bi_metric1      , COUNT(if(order_type = '订单类型 2', buyer_id, NULL)) AS bi_metric2      , SUM(if(order_type = '订单类型 2', gmv, 0)) AS bi_metric3      , COUNT(if(order_type = '订单类型 3', buyer_id, NULL)) AS bi_metric4      , SUM(if(order_type = '订单类型 3', gmv, 0)) AS bi_metric5      , COUNT(if(order_type = '订单类型 4', buyer_id, NULL)) AS bi_metric6      , SUM(if(order_type = '订单类型 4', gmv, 0)) AS bi_metric7    FROM (      SELECT *      FROM dm_zbk.da_self_analysis_demo    ) mid_dataset
度量名在订单类型上时的 SQL 如下:
    SELECT COUNT(if(order_type = '订单类型 1', buyer_id, NULL)) AS bi_metric0      , COUNT(if(order_type = '订单类型 2', buyer_id, NULL)) AS bi_metric1      , COUNT(if(order_type = '订单类型 3', buyer_id, NULL)) AS bi_metric2      , COUNT(if(order_type = '订单类型 4', buyer_id, NULL)) AS bi_metric3      , SUM(if(order_type = '订单类型 1', gmv, 0)) AS bi_metric4      , SUM(if(order_type = '订单类型 2', gmv, 0)) AS bi_metric5      , SUM(if(order_type = '订单类型 3', gmv, 0)) AS bi_metric6      , SUM(if(order_type = '订单类型 4', gmv, 0)) AS bi_metric7    FROM (      SELECT *      FROM dm_zbk.da_self_analysis_demo    ) mid_dataset

3.3 计算字段

有赞BI 平台也允许用户自己写一个 SQL 片段对数据集进行加工,生成额外的虚拟字段。

有赞BI平台实现原理

图 3.3 普通与带聚合运算的计算字段
如图 3.3,如果用户写的是非聚合类的表达式,就当做一般的字段处理。如果用户写的是聚合类的表达式,当字段被拖拽到数值区域的时候,我们不需要对这个聚合表达式再做一次聚合,使用用户原本的表达式即可。

如果用户写的聚合类的计算字段与列维度共存的时候,需要对用户的表达式进行加工,例如:

有赞BI平台实现原理

图 3.4 带聚合运算的计算字段
当一个聚合类型的计算字段与订单类型列维度共存的时候,生成的 SQL 为:
SELECT try( sum(if(order_type = '订单类型 3', gmv , 0)) ) AS bi_metric0, try( sum(if(order_type = '订单类型 4', gmv , 0)) ) AS bi_metric1, try( sum(if(order_type = '订单类型 2', gmv , 0)) ) AS bi_metric2, try( sum(if(order_type = '订单类型 1', gmv , 0)) ) AS bi_metric3FROM (SELECT *FROM  dm_zbk.da_self_analysis_demo) mid_dataset
可以看到我们在用户的 sum 函数外部添加了 try 函数,因为表达式在某些情况下,比如除法分母为零的时候可能会报错。在内部添加了 if 条件,因为订单类型列维度会有不同的取值,根据这些不同的取值结合用户写的 sum 聚合函数构造 sum if 结构的查询表达式。对用户 SQL 节点修改是通过 antlr 来实现的。antlr 的 parser 在 parse sql 的时候可以使用观察模式,允许对节点遍历的前后添加自己定义的回调函数。当我们遍历到聚合函数的时候,使用 TokenStreamRewriter 去 replace 对应的字符串,对聚合函数前后加上 try,同时根据列维度唯一值的不同,添加不同的 if 条件即可。

四、总结与展望

有赞 BI 平台是有赞数据中台对数据可视化能力复用的结晶,利用有赞 BI 平台可以为内部数据使用与分析提供高效便捷的能力支撑。未来有几个重要的事情:
‍‍

版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:有赞BI平台实现原理
喜欢 (0)

您必须 登录 才能发表评论!