--增量导入(仅新增 /user/bin/sqoopimport "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \ --connect 'jdbc:mysql://192.168.88.80:3306/yipin?useUnioncode=true&characterEncoding=UTF-8&autoReconnect=true' \ --username root \ --password 123456 \ --query 'select *,'${TD_DATE}' from t_user_login where 1=1 and login_time between '${TD_DATE} 00:00:00' and '${TD_DATE} 23:59:59' and \$CONDITIONS' \ --hcatalog-database yp_ods \ --hcatalog-table t_user_login \ -m 1
--增量导入(更新 + 新增 --注意这里login_time 和 update_time之间是或or的关系(只要有更新,或者新增都要 /user/bin/sqoopimport "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \ --connect 'jdbc:mysql://192.168.88.80:3306/yipin?useUnioncode=true&characterEncoding=UTF-8&autoReconnect=true' \ --username root \ --password 123456 \ --query 'select *,'${TD_DATE}' from t_user_login where 1=1 and login_time between '${TD_DATE} 00:00:00' and '${TD_DATE} 23:59:59' or update_time between '${TD_DATE} 00:00:00' and '${TD_DATE} 23:59:59' and \$CONDITIONS' \ --hcatalog-database yp_ods \ --hcatalog-table t_user_login \ -m 1
Data Warehouse Detail
知道DWD层的作用
掌握拉链表作用,拉链表公式,以及拉链表的实现方式(创建临时表)
DWD层作用
负责清洗转换,区分维度表dim_xxx和事实表fact_xxx
食用前必看
3种导入方式:拉链导入(增量及更新) ,全量覆盖导入, 增量导入(instance1,2,3 24张表中,有20张表是拉链表,订单评价表和登录记录表是增量表(增量导入),区域字典表、时间维度表是全量覆盖导入 这里的重点是拉链表-要有start_time 和 end_time这两个字段来维护历史数据 这就是拉链表 拉链表公式: (旧的拉链表 left join 增量信息) union all 增量信息
拉链表Pseudocode
1 2 3 4 5 6 7 8 9 10 11 12
insert overwrite table fact_shop_order_tmp partition(start_date) select ... xxx, .... if(增量信息.id=nullor 旧的拉链表.end_date='9999-12-31',旧的拉链表.end_date,date_sub(增量信息.start_date-1)) -- if后的信息判断旧的拉链表的end_date需不需要修改(两种情况不需要修改),需要修改就用增量信息的start_date - 1 from 旧的拉链表 leftjoin 增量信息 on 旧的拉链表.id=增量信息.id unionall select * from 增量信息;
拉链导入(增量及更新)
订单事实表,循环与拉链导入(因为拉链表是dwd层,所以要用sqoop抽取到ODS层,再到DWD层
增量导入的第一步必定是全量导入
1 2 3 4 5 6 7 8 9 10
insert overwrite table yp_dwd.fact_shop_order PARTITION (start_date) -- overwrite后必须有table select id,order_num,buyer_id, case order_from -- 这里算作数据转换,数据的清洗有空值过滤,列值裁剪 when1then'Android' when2then'IOS'.... endas order_from .... '9999-99-99'as end_date, -- 手动定义end_time dt as start_date -- dt 作为start_time from yp_ods.t_shop_order;
Step1:增量导入更新+新增,使用sqoop从业务数据库中抽取到ODS层
1 2 3 4 5 6 7 8
/usr/bin/sqoopimport "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \ --connect 'jdbc:mysql://192.168.88.80:3306/yipin?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true' \ --username root \ --password 123456 \ --query "select *, '2021-11-30' as dt from t_shop_order where 1=1 and (create_time between '2021-11-30 00:00:00' and '2021-11-30 23:59:59') or (update_time between '2021-11-30 00:00:00' and '2021-11-30 23:59:59') and \$CONDITIONS" \ --hcatalog-database yp_ods \ --hcatalog-table t_shop_order \ -m 1
select xxx FROM yp_dwd.fact_shop_order o -- 订单明细表(订单主表) --订单副表 LEFTJOIN yp_dwd.fact_shop_order_address_detail od on o.id=od.id and od.end_date='9999-99-99' --订单组 LEFTJOIN yp_dwd.fact_shop_order_group og on og.order_id = o.id and og.end_date='9999-99-99' --and og.is_pay=1 是否支付的过滤 0未支付 1 已支付 --订单组支付信息 LEFTJOIN yp_dwd.fact_order_pay op ON op.group_id = og.group_id and op.end_date='9999-99-99' --退款信息 LEFTJOIN yp_dwd.fact_refund_order refund on refund.order_id=o.id and refund.end_date='9999-99-99' --and refund.refund_state=5 退款状态 5表示退款已经完成 --结算信息 LEFTJOIN yp_dwd.fact_order_settle os on os.order_id = o.id and os.end_date='9999-99-99' --商品快照 LEFTJOIN yp_dwd.fact_shop_order_goods_details ogoods on ogoods.order_id = o.id and ogoods.end_date='9999-99-99' --订单评价表 LEFTJOIN yp_dwd.fact_goods_evaluation e on e.order_id=o.id and e.is_valid=1 --订单配送表 LEFTJOIN yp_dwd.fact_order_delievery_item d on d.shop_order_id=o.id and d.dispatcher_order_type=1and d.is_valid=1 where o.end_date='9999-99-99';
DWB店铺宽表(手撕Pseudocode
1 2 3 4 5 6 7 8
-- 如果这里是left join则必须最子集在最前面(左, select t3.name, t2.name, t1.name from dim_tistrict t1 -- t1做县区表 leftjoin dim_tistrict t2 on t1.pid=t2.code -- t2 做市表 leftjoin dim_tistrict t3 on t2.pid=t3.code -- t3 做省表
商品明细宽表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-- 商品分类表dim_goods_class的level有3个值1,2,3分别代表大中小类 -- 总结一句话,大类表中不能有中类和小类字段,即class3中不能有level=1或2 select-- 这里只提取大中小类字段的名称,不提取id(更多信息详情见之前的blog case class1.level -- 当小类表中level字段为3(小类) 则为正确字段,否则为错误字段 when3then class1.name elsenullendas min_class_name, case-- 当小类表中level字段为2(中类)字段也是可以的,但是大类表中不能有小类(level=1)中类(level=2)字段 when class1.level=2then class1.name when class2.level=2then class2.name elsenullendas mid_class_name case-- max_class字段大中小类表中都有 when class1.level=1then class1.name when class2.level=1then class2.name when class3.level=1then class3.name elsenullendas max_class_name from yp_dwd.dim_goods_class class1 -- class1 做小类表 leftjoin dim_goods_class class2 on class1.parent_id=class2.id -- class2做中类表 leftjoin dim_goods_class class3 on class2.parent_id=class3.id -- class3做大类
Data Warehouse Service
知道DWS层的作用
掌握DWS层的重点和难点(去重的原理)
掌握该层销售,商品主题使用链式CTE表达式的作用,以及达成的效果
Keys:
row_number( ) 窗口函数 + CTE表达式 + where字段=1 进行去重
grouping(多个字段) = 十进制,转二进制然后0代表有,1代表没有
金额相关指标-分别按照八个维度进行计算,case 店铺维度 then sum(if(order_rn=1 and 店铺不为空,order_amt,0)),这里注意统计小程序,ios,安卓,pc成交额时 and 后面还要跟order_from=’iOS’
订单量相关指标(八个维度),方法同上
DWS层作用
获取各种主题的日统计宽表,销售,商品,用户宽表
销售主题日统计宽表
去重原理:row_number() over(partition by ) rn CTE 然后where rn=1(根据什么分组就根据什么去重)
Stage1:建表
1 2 3 4 5 6 7
createtable yp_dws.dws_sale_daycount( -- 14个维度字段(城市,商圈,店铺,品牌,大类,中类,小类的id,name) -- 分组类型 即属于那种维度组合 group_type -- 16个指标字段 )partitioned by (dt string) row format delimited fields terminated by'\t' stored as orc tblproperties('orc.compress'='snappy');