离线数仓项目
离线数仓怎么设计分层的¶
标准五层架构: - ODS:操作数据层,原始数据接入 - DWD:明细数据层,清洗后的最小粒度明细事实表 - DIM:维度层,一致性维度表 - DWS:汇总数据层,基于维度的公共汇总表 - ADS:应用数据层,面向应用的最终指标
离线数仓有哪些数据域?¶
(1)用户域:登录、注册 (2)流量域:启动、页面、动作、故障、曝光 (3)交易域:加购、下单、支付、物流 (4)工具域:领取优惠卷、使用优惠卷下单、使用优惠卷支付 (5)互动域:点赞、评论、收藏
介绍一下离线数仓的构成和数据流转¶
业务侧:MySQL 数据库、手机 APP 埋点日志 采集层:Maxwell (MySQL) / Flume (日志) → HDFS ODS 数仓内层: ODS → DIM(维度整合) ODS → DWD(明细清洗) DWD + DIM → DWS(指标汇总) DWS → ADS(可视化专用报表) 应用层:ADS 同步 MySQL → Apache Superset 制作仪表盘、地图、饼图、数字指标看板
调度用的是什么¶
Dolphinscheduler,项目中使用流程: 1)在 DS 网页创建离线数仓 DAG 工作流 2)按分层顺序添加任务节点,绑定对应 bin 目录 shell 脚本 3)设置每日凌晨定时执行,配置失败邮件告警 4)历史数据出错时,手动输入日期批量重跑补数
举具体例子说明事实表和维度表你怎么设计的¶
商品维度 dimskufull : 分析订单、优惠券、活动时,都需要商品名称、品类、品牌、属性;原始业务表 sku/spu/ 三级品类 / 品牌分散,每次关联多表查询效率极低,因此反范式整合为一张商品维度表
用户维度 dimuserzip(拉链维度,记录历史变更) : 用户姓名、手机号、等级会修改;如果用每日全量表,每天存一份全量用户,存储空间爆炸。拉链表用startdate/enddate记录每条维度记录的生效时间段,一条数据永久保存,变更仅新增一条过期记录。
交易域下单事务事实 dwdtradeorderdetailinc(事务型事实表):定义了用户提交订单明细(最小粒度:1 个订单里 1 个 SKU=1 行事实)这个业务行为
项目中的数据仓库的分层、分域是怎么做的?数仓是怎么划分主题域的?其中的表有哪些指标¶
- 分层
- 标准五层:ODS(操作数据层)、DWD(明细数据层)、DIM(维度层)、DWS(汇总数据层)、ADS(应用数据层)
| 数据域 | 业务过程 |
|---|---|
| 交易域 | 加购、下单、取消订单、支付成功、退单、退款成功 |
| 流量域 | 页面浏览、启动应用、动作、曝光、错误 |
| 用户域 | 注册、登录 |
| 互动域 | 收藏、评价 |
| 工具域 | 优惠券领取、优惠券使用(下单)、优惠券使用(支付) |
- 分域
- 用户域:登录、注册
- 流量域:启动、页面、动作、故障、曝光
- 交易域:加购、下单、支付、物流
- 工具域:领取优惠卷、使用优惠卷下单、使用优惠卷支付
- 互动域:点赞、评论、收藏
- 主题:流量、交易、用户、互动
-
指标:
-
统计当日的首页和商品详情页独立访客数(流量域页面浏览各窗口汇总表)
- 统计各省份各窗口订单数和订单金额(交易域省份粒度下单各窗口汇总表)
- 统计七日回流用户和当日独立用户数(统计七日回流用户和当日独立用户数)
DWD和DIM怎么设计的,有什么指标¶
1. DIM层(维度层)的设计与“指标”¶
- 主要维度表及其属性:
- 商品维度(
dim_sku_full):包含SKU_ID、价格、名称、三级品类、品牌、平台属性、销售属性等。 - 用户维度(
dim_user_zip,拉链表):包含用户ID、姓名、手机号、邮箱、性别、等级,以及拉链表的起始日期和结束日期(用于记录历史变化)。 - 优惠券/活动维度(
dim_coupon_full/dim_activity_full):包含优惠券/活动的名称、类型、优惠规则(如满减金额、折扣)等。 - 地区/日期维度(
dim_province_full/dim_date):包含省份名称、地区编码,以及日期的年/月/周/是否工作日等。
2. DWD层(明细数据层)的设计与原子指标¶
- 主要事实表及其原子指标(度量值):
- 交易域:
dwd_trade_cart_add_inc(加购事实):度量值为sku_num(加购件数)。dwd_trade_order_detail_inc(下单明细事实):度量值为sku_num(件数)、split_original_amount(原始金额)、split_activity_amount(活动分摊优惠)、split_coupon_amount(券分摊优惠)、split_total_amount(最终金额)。dwd_trade_pay_detail_suc_inc(支付成功事实):度量值为sku_num、split_payment_amount(支付金额)。dwd_trade_trade_flow_acc(累积快照事实):记录下单/支付/完成的时间戳及金额,用于计算时间间隔。
- 流量域:
dwd_traffic_page_view_inc(页面浏览事实):度量值为during_time(页面停留时长,毫秒)。
- 用户域:
dwd_user_register_inc/dwd_user_login_inc(注册/登录事实):记录注册/登录发生的具体时间。
DWS层存放的哪些指标¶
- 设计核心:DWS层基于指标体系(派生指标),对DWD层的明细数据进行提前聚合计算。目的是复用计算结果,减少重复计算。存储粒度通常是“统计周期 + 统计粒度 + 业务过程”。
- 存放内容(派生指标/汇总指标):存放已经按照维度(用户、商品、省份、会话等)聚合好的统计值。
按统计周期划分,DWS层主要存放以下指标:
(1)最近1日汇总表(_1d)¶
- 交易域用户-商品粒度(
dws_trade_user_sku_order_1d):order_count_1d(下单次数)、order_num_1d(件数)、order_original_amount_1d、activity_reduce_amount_1d、coupon_reduce_amount_1d、order_total_amount_1d。 - 交易域用户粒度(
dws_trade_user_order_1d/payment_1d):下单/支付次数、件数、支付金额。 - 交易域省份粒度(
dws_trade_province_order_1d):各省份下单次数、原始金额、优惠金额、最终金额。 - 互动域商品粒度(
dws_interaction_sku_favor_add_1d):favor_add_count_1d(商品被收藏次数)。 - 流量域会话/访客粒度(
dws_traffic_session_page_view_1d):during_time_1d(浏览时长)、page_count_1d(浏览页面数)、view_count_1d(访问次数)。
(2)最近n日汇总表(_nd,如7日/30日)¶
- 将上述
_1d表的指标按用户/省份/商品进行累加,例如: order_count_7d/30d、order_total_amount_7d/30d(累计订单量和金额)。order_num_7d/30d(累计购买件数)。
(3)历史至今汇总表(_td)¶
- 交易域用户粒度(
dws_trade_user_order_td):order_date_first(首次下单日期)、order_date_last(末次下单日期)、order_count_td(历史累计下单次数)、total_amount_td(历史累计消费金额)。 - 用户域登录粒度(
dws_user_user_login_td):login_date_first/last(首次/末次登录日期)、login_count_td(历史累计登录次数)。
DWD层建多少张表¶
按数据域划分,具体如下:
-
交易域(5张) dwdtradecartaddinc:加购事务事实表 dwdtradeorderdetailinc:下单事务事实表 dwdtradepaydetailsucinc:支付成功事务事实表 dwdtradecartfull:购物车周期快照事实表 dwdtradetradeflowacc:交易流程累积快照事实表
-
工具域(1张) dwdtoolcouponusedinc:优惠券使用(支付)事务事实表
-
互动域(1张) dwdinteractionfavoraddinc:收藏商品事务事实表
-
流量域(1张) dwdtrafficpageviewinc:页面浏览事务事实表
-
用户域(2张) dwduserregisterinc:用户注册事务事实表 dwduserlogininc:用户登录事务事实表
DIM层有哪些表¶
| 表名 | 维度类型 | 存储方式 | 核心用途 |
|---|---|---|---|
| dimskufull | 商品 | 每日全量分区 | 品类、商品、品牌分析 |
| dimcouponfull | 优惠券 | 每日全量分区 | 优惠券抵扣、领用统计 |
| dimactivityfull | 活动 | 每日全量分区 | 各类活动成交额分析 |
| dimprovincefull | 省份地区 | 每日全量分区 | Superset 全国地图可视化 |
| dimpromotionpos_full | 广告坑位 | 每日全量分区 | 首页广告曝光转化 |
| dimpromotionrefer_full | 推广渠道 | 每日全量分区 | 渠道引流转化 |
| dimuserzip | 用户 | 拉链表 | 用户分层、用户行为分析 |
| dim_date | 日期 | 静态无分区 | 所有报表时间维度分组 |
DWS的主题有哪些?有哪些指标?¶
- 主题:流量、交易、用户
- 指标:
- 统计当日的首页和商品详情页独立访客数(流量域页面浏览各窗口汇总表)
- 统计各省份各窗口订单数和订单金额(交易域省份粒度下单各窗口汇总表)
- 统计七日回流用户和当日独立用户数(统计七日回流用户和当日独立用户数)
数据去重你sql怎么写的?select distinct?group by?¶
结论: 能使用group by代替distinct就不要使用distinct 追问:distinct 效率更高还是 group by 效率更高?为什么? 默认情况下,distinct会被hive翻译成一个全局唯一reduce任务来做去重操作,因而并行度为1 而group by则会被hive翻译成分组聚合运算,会有多个reduce任务并行处理,每个reduce对收到的一部分数据组,进行每组聚合(去重) 高版本的hive,对distinct进行了优化,其执行计划和group by的一样,已经不会出现低版本的一个reduce现象
查询直接用的hive吗?¶
离线数仓的ETL 加工通过Hive进行,ETL 阶段没有替代方案,只能用 Hive 处理 HDFS 上的海量离线数据。 ADS 层预聚合报表表(Hive)→ 通过 SQL 把指标导出同步到 MySQL → Superset 连接 MySQL 查询指标做图表 文档里的adsorderbyprovince、adscoupon_stats这类报表表,都会落地 MySQL 供可视化使用。 只有极少数场景会在 Superset 直连 Hive 做临时分析。
你的数仓数据加工用hiveSQL,为什么用hive,为什么不用sparksql呢¶
- 数据规模较小,并且延迟不是非常关键,所以考虑使用Hive。Hive可以轻松处理小规模的数据,并且具有低延迟的查询能力。
- 如果只需要进行简单的数据查询和报表分析,而不需要进行复杂的数据处理和计算,考虑使用Hive
DWS的结果是怎么聚合的?¶
问的是在分组开窗聚合时,聚合计算是怎么做的
在上面的例子中,经过开窗得到的 WindowedStream 直接调用 reduce 方法,在里面定义用旧的值加上新的值得到聚合结果。并在窗口闭合后补充窗口起始时间和结束时间。将时间戳置为当前系统时间