• 大数据项目 --- 电商数仓(一)


    这个项目实在数据采集基础使用的,需要提前复习之前学的东西,否则的话就是很难继续学习.详见博客数据项目一 ---数据采集项目.大数据项目 --- 数据采集项目_YllasdW的博客-CSDN博客大数据第一个项目笔记整理https://blog.csdn.net/m0_47489229/article/details/127477626

    目录

    一. 采集项目架构

    二. 用户采集平台

    三. 业务采集架构

    四. 后台商品管理表格

    5. 电商业务表格

    6.采集项目压缩编码修改

    七.数仓简介

    八.范式

    第一范式

    第二范式

    第三范式

    九.维度建模和关系建模

    关系建模

    维度建模

    ​编辑

    维度表和事实表

    十.维度建模分类

    十一.数仓建模全过程(绝对重点)

    一.ODS层 --- 用户存放的数据

    二.DIM层和DWD层

    三.DWS层与DWT层

    十二.Hive搭建

    一.架构说明

    二.hive配置

    十三.HiveOnSpark搭建

    一.上传包

    二.配置spark的环境变量$ sudo vim /etc/profile.d/my_env.sh

    三.新建spark配置文件,因为我们这里使用的是hive on spark$ vim /opt/module/hive/conf/spark-defaults.conf

    四.向HDFS上传Spark纯净版jar包

    五.修改hive-site.xml文件 --- 真正的将hive和spark进行关联

    六.Hive on Spark测试

    十四.创建多队列的好处

    十五.创建hive队列

    十六.datagrip工具安装

    十七.ODS层用户行为日志(建表+加载数据) 

    十八.脚本之中单引号和双引号之间的区别

     十九.ODS_业务数据建表

    二十.ODS_业务数据脚本

    二十一.ODS_索引问题

    二十二.DWD层_get_json_object --- 工薪阶层

    二十三.创建启动日志

    二十四.加载数据

    二十五.hive读取文件

     二十六.页面日志解析

    二十七.动作日志建表

    二十八.UDTF函数思想

    二十九.DWD_创建永久UDTF函数

    三十.DWD_动作日志解析完成 

     三十一.DWD_曝光日志

     三十二.页面信息解释

    三十三.错误日志表分析

    三十四.DWD_商品维度解析

    三十五.DWD_优惠券维度表

    三十六.活动维度表(全量)

    三十七.DWD_业务_维度退化

    三十八.DWD_业务_ETL清洗

    三十九.DWD_业务_活动维度

    四十.DWD_业务_地区维度

    四十一.DWD_业务_时间维度

    四十二.DWD_业务_支付事实表

    四十三.DWD_业务_退款事实表

    四十四.DWD_业务_评价事实表

    四十五.DWD_业务_订单详情事实表-217

    四十六.DWD层_业务_订单加购表

    四十七.DWD层_业务_收藏事实表

    四十八.DWD层_业务_优惠券领用事实表

    四十九.DWD_业务_系统函数(concat、concat_ws、collect_set、STR_TO_MAP)

    五十.DWD_业务_订单表分析

    五十一.DWD_业务_用户拉链表(非常重要的)

    五十二.DWD_业务导入脚本

    五十三.DWS层_DWT层

    五十四.DWS_DWT层术语

    五十五.DWS_DWT层系统函数

    五十六.DWS_DWT层复杂数据类型

    五十七.DWS层设备行为宽表分析

    五十八.DWT层设备行为宽表完成

    五十九.DWS层_会员行为宽表分析

    六十.DWT层_会员行为宽表完成

    六十一.数据仓库小总结

    六十二.数据仓库_宽表回顾

    六十三.DWS_商品主题每日统计

    六十四.DWT_商品主题宽表_数据装载

    六十五.DWS_活动每日统计宽表

    六十六.DWT_活动主题宽表

    六十七.DWS-DWT_地区主题表

    六十八.DWS_DWT数据导入脚本

    六十九.ADS_设备主体_活跃设备---这里的方案是很多的

    七十.ADS_每日新增设备进行导入

    七十一.ADS_沉默用户

    七十二.多表join出现的问题_使用COALESCE函数解决

    七十三.ADS_设备主题_留存

    七十四.ADS_设备主题_本周回流

    七十五.ADS_设备主题_流失用户数

    七十六.Hiveserver2_heap_size

    七十七.ADS_设备主题_最近三周连续活跃

    七十八.ADS_设备主题_最近七天连续三天的活跃次数

    七十九.ADS_会员主题信息表

    八十.ADS_漏斗分析

    八十一.ADS_商品主题_商品个数

    八十二.ADS_商品主题_全局TopN

    八十三.ADS_商品主题_退款率

    八十四.ADS_商品主题_商品差评率

    八十五.ADS_营销主题_下单支付统计

    八十六.ADS_营销主题_支付信息统计

    八十七.ADS_商品主题_品牌复购率

    八十八.ADS_地区建表语句

    八十九.ADS_脚本的建立


    一. 采集项目架构

    我们使用的体系是Hadoop体系,是属于这个生态的.

    为什么要使用数据仓库,因为后面使用机器学习的来源是使用数据仓库的,以及后面学习的用户画像.传统的公司收集的数据都是来自于业务数据,但是大数据体系还是要收集来自于用户产生的实时,解决问题需要考虑业务思维.

    如何采集用户数据 --- 埋点方法(行为会被记录下来),将其使用日志服务器Springboot进行采集,得到logFile,再通过Flume进行采集.Flume采集logFile文件的时候,它的源于源之间是不同的,Flume可以保证数据的原子性和一致性,翻译成人话就是可以保证数据不丢失.

    面试的一些问题,架构设计原因(防止压价,要钱):
    ①Exec Source在生产环境是不会使用这个的,因为这个Source是不能够保证put完全成功的,一旦要是失败会出现丢失数据的情况,为了更强的保证性,可以使用Taildir Source.Flume事务的代码是根据相应的channal决定的,生产环境一般是不使用Exec Source,也就是相应的logFile使用的是Taildir Source.
    Exec Source的父类是Event Driven,但是Taildir Source的父类是Puable Source,后者的可靠性是比原来的可靠性高的,因此,这里的用户数据是使用的Taildir Source.
    ②这里加入Kafka的原因是因为HDFS的吞吐量是不如Kafka高.因此这里放入Kafka的方法是可以直接使用SparkStreaming将相应的数据进行实时指标分析;另一个原因还Kafka是可以一对多,在这个领域是比较出色的,方便多个源使用同一个数据.
    ③Kafka是个消息队列,是用来存储数据.Flume是主要的采集部分.如果要是没有Flume,也是可以读进Kafka,那为什么还要使用Flume?Flume做的最多的是Source和Sink,用户数据采集的地方,第一个Flume和第二个Flume是可以不用的.那为什么要使用呢?为啥不用现成的的Flume,要自己重复造个轮子呢,是完全没有必要的.

    二. 用户采集平台

    继续深挖刚才的细节:
    ①第一个(上游)Flume使用的Taildir Source - Kafka Channal,第二个(下游)Flume使用的是相应的Kafka Source - File Channal - HDFS Sink.第一个Flume也可以使用Taildir Sourc - File Channal - Kafka Sink,但是为什么我们没有使用这个架构,因为中间多了一层,不如是直接将上面的那一层进行省略掉.(复杂度上升,并且会变得复杂,吃资源,尤其是Channal这个部分).
    那为啥下游不使用Kafka Source - HDFS Channal,因为拦截器的使用.上游是ETL拦截器,为了过滤不合格的json格式的文件.下游是使用的timeStamp拦截器,这个作用是为了解决相应的零点漂移(人话:防止昨天的数据,出现在今天采集的数据之中).这里的是时间戳timeStamp拦截器可以是放在上游的,但是不太好,如果要是在上游的时候使用了,就会产生相应的带有Header部分,导致在写入Kafka的时候,处理的数据是EVENT格式的文件,并不是JSON格式(恍然大悟).
    ②上面的问题解决方式,使用Kafka时间戳拦截器,会在执行的过程中产生大量的冗余.
    ③下游的Flume为什么搞一个File Channal?回答:我们想过很多的方案,这里的拦截器是不能够写在上游的Flume之中.使用Kafka Channal会导致大量的对象的生成,会出现大量的垃圾回收,这里的性能是不能采用这个方式进行相应的采集的,因此没有使用Kafka Channal.使用File Channal的性能还是过的去的,就是这样回答.

    三. 业务采集架构

    问题这里为什么使用Sqoop?
    Sqoop是使用的阿里云啥的,基本是一天一采集,直接放到相应的HDFS之中.为什么要使用Sqoop为什么要用它,因为它虽然不是最先进的,但是使用了那么长的时间,它的性能是完全够用的.现在也在考虑将这个地方进行升级,但是没有充足的测试.

    四. 后台商品管理表格

    这里的C位表一定是相应的订单表 用户表 商品表. 商品表这个东西分为SPU和SKU,这里的SPU指一个完整的整体,以SKU为单位,以IPHONE14为例子.

    5. 电商业务表格

    这里的电商数据业务表格的说明,是需要将之前学习过的东西,也就是所谓的sql之中的东西放入到IDEA之中进行查看。对于项目一之中的东西进行复习。

    就是实际之中的表并不是那么少的,会很多的。

    6.采集项目压缩编码修改

    原来的Flume我们是使用的lzo进行的压缩,这里需要改成相应的gzip进行压缩。
    1)这里我之前设置的路径是$ /opt/module/flume-1.9.0/jobs/gmall
    $ vim kafka-flume-hdfs.conf --- 将里面的配置进行修改,如下所示: lzop-gzip

    2)将sqoop之中的东西采用gzip进行压缩

    在根目录下的bin目录之中的mysql_to_hdfs_init.sh 脚本进行修改,将lzop ------org.apache.hadoop.io.compress.GzipCodec

    将上图之中的这句话给删除。在mysql_to_hdfs.sh脚本之中进行与上述操作相同的操作。

    为什么要用lzop而不用snap?学一下依赖的使用,并且lzop会产生相应的切片。flume采集过程使用lzop没有问题,snap使用flume。sqoop使用lzop文件不会大的离谱。snap不会产生相应的切片。

    七.数仓简介

    数仓分层如下所示:

    ODS层:原始数据层,直接加载原始的数据、日志,数据保持原貌,不作处理。
    DWD层:对ODS层的数据进行相应的清洗(去除空值、脏数据等),保存业务事实明细。一行的数据代表一次业务行为,例如一次下单。
    DIM层:维度层,保存维度数据,主要是对业务事实的描述信息,例如何人、何时、何地等。我早上在宿舍11点醒的,12点半吃的饭。
    DWS层:对于DWD层做一个汇总。一行信息代表一个主题对象一天的汇总行为,例如:一个用户一天的下单次数。
    DWT层:对于DWS层的一个汇总。一行的信息代表一个主题对象的累积行为,例如一个用户从注册那一天开始到现在一共下了多少单。
    ADS层:为各种统计报表提供的数据。

    数据仓库为什么要进行分层?
    ①复杂的问题简单化
    ②减少重复数据的开发
    ③隔离原始数据

    基本的概念(先是把相应的概念进行炒作,接下来就是进行赚钱)
    数据海 数据仓库 数据集[这里的几个概念就是数据大小的区别,总而言之都是数据]

    表名命名规范

    • ODS层命名为ods_表名
    • DIM层命名为dim_表名
    • DWD层命名为dwd_表名
    • DWS层命名为dws_表名  
    • DWT层命名为dwt_表名
    • ADS层命名为ads_表名
    • 临时表命名为tmp_表名

    表字段类型命名规范

    • 数量类型为bigint
    • 金额类型为decimal(16, 2),表示:16位有效数字,其中小数部分2位(double不够精确的)
    • 字符串(名字,描述信息等)类型为string
    • 主键外键类型为string
    • 时间戳类型为bigint

    八.范式

    数据建模必须遵循一定的规则,在关系数建模中,这种规则就是范式。优点:可以减少数据的冗余性。缺点:获取数据时,需要通过Join拼接出最后的数据。分类:范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。

    建模的含义就是创建一个数学模型或者理论模型用来模拟现实生活之中的一些数据。

    函数依赖:概念麻烦,用人话表示。

    上面的分数是需要使用学号和课名表示才能够得知,这叫做完全函数依赖。
    由学号和课名可以推导出一个人的姓名,但是只是知道学号也是可以知道姓名,这就是所谓的部分函数依赖。 
    学号-系名-系主任------传递函数依赖

    第一范式

    原则:属性不可分割

    上述的表格并不是符合第一范式的,商品之中的数据并不是原子数据项,是可以进行分割的。将上述的表变成是符合第一范式的类型是如下所示:

    实际上,1NF是所有关系型数据库的最基本的要求,如果一个表设计不是符合第一范式的,那么一定是有问题的。

    第二范式

    原则:不存在“部分函数依赖”

    上面的表格是明显存在部分依赖的,分数是依赖于学号和课名,但是姓名并不是依赖于学号和课名的。因此,将上述的表进行拆开,分成两个表进行分析。

            

    上述的两个表示没有部分依赖的,因此就是将上述的表格二范式化了。将一张大表分成了两个小表。

    第三范式

    原则:不能存在传递函数依赖

    上面的表示学号 -> 系名 -> 系主任,将上述的表格进行相应的拆分。

    进而符合第三范式过程。

    小小总结:范式越高,数据越是清晰一些,一致性越是好一些 ------- 容易差错。时间代价降低,空间代价会上升。【空间换取时间】 

    九.维度建模和关系建模

    为了降低查询时所消耗的时间代价,减少使用join,一般是范式一应用于数据仓库之中。

    关系建模和维度建模是两种数据仓库的建模技术。关系建模由Bill Inmon所倡导,维度建模由Ralph Kimball所倡导。

    关系建模

    关系建模将复杂的数据抽象为两个概念——实体和关系,并使用规范化的方式表示出来。

    关系模型严格遵循第三范式(3NF)数据冗余程度低,数据的一致性容易得到保证。由于数据分布于众多的表中,查询会相对复杂,在大数据的场景下,查询效率相对较低。
    数据仓库一般是不使用这种范式建模的,因为这里的东西太碎了,代价太高了。(要写很多的join)

    维度建模

    上图之中所有的信息是围绕中间的事实进行联系,进而得到相应的维度建模。

    维度模型以数据分析作为出发点,不遵循三范式,故数据存在一定的冗余。维度模型面向业务,将业务用事实表和维度表呈现出来。表结构简单,故查询简单,查询效率较高。在大数据之中应用是比较多的。

    数据仓库的第一步是进行数据规划,确定数据仓库需要哪些表格。维度建模,用来提高查询效率,发生在DWD和DIM层之中。

    维度表和事实表

    维度表:一般是对事实的描述信息。每一张维表对应现实世界中的一个对象或者概念。维度一定是一个抽象的东西,例如:用户、商品、日期、地区等。煎饼果子就不是维度表。   

    维表的特征:①维表的范围很宽(具有多个属性、列比较多)②跟事实表相比,行数相对较小:通常< 10万条 ③内容相对固定:编码表

    时间维度表:

    日期ID

    day of week

    day of year

    季度

    节假日

    2022-11-07

    2

    1

    1

    元旦

    2022-11-08

    3

    2

    1

    2022-11-09

    4

    3

    1

    2022-11-10

    5

    4

    1

    2022-11-11

    6

    5

    1

    事实表:事实表中的每行数据代表一个业务事件(下单、支付、退款、评价等)。“事实”这个术语表示的是业务事件的度量值(可统计次数、个数、金额等)。也就是将上面的维度变成id,其余的信息变成度量值。例如:2022年11月7日,姚毅伟同学(哈哈哈)在遵义的某团偷偷花了250块钱买了八瓶六味地黄丸。维度表:时间、用户、商品、商家。事实表:250块钱、八瓶。

    每一个事实表的行包括:具有可加性的数值型的度量值、与维表相连接的外键,通常具有两个和两个以上的外键。

    事实表的特征:①非常的大 ②内容相对的窄:列数较少(主要是外键id和度量值)③经常发生变化,每天会新增加很多。

    分类:
    1)事务型事实表
    以每个事务或事件为单位,事件一旦被提交不能更改,只能增加。

    2)周期型快照事实表
    周期型快照事实表中不会保留所有数据,只保留固定时间间隔的数据,例如每天或者每月的销售额,或每月的账户余额等。

    3)累积型快照事实表
    累计快照事实表用于跟踪业务事实的变化。例如,数据仓库中可能需要累积或者存储订单从下订单开始,到订单商品被打包、运输、和签收的各个业务阶段的时间点数据来跟踪订单声明周期的进展情况。当这个业务过程进行时,事实表的记录也要不断更新。

    十.维度建模分类

    在维度建模的基础上又分为三种模型:星型模型、雪花模型、星座模型。

    1.星型模型

     2.雪花模型

    雪花模型更加靠近于范式三类型,相对而言,星型模型是更加接近于范式一类型的。一般我们是使用星型模型进行数据分析。

    3.星座模型

    星座表与前面的两个情况的区别是事实表的数量,星座模型是基于多个事实表。

    十一.数仓建模全过程(绝对重点)

    一.ODS层 --- 用户存放的数据

    1)HDFS 用户行为数据
    2)HDFS 业务数据

    针对HDFS上的用户行为数据和业务数据,我们如何规划处理?
    (1)保持数据原貌不做任何修改,起到备份数据的作用。
    (2)数据采用压缩,减少磁盘存储空间(例如:原始数据100G,可以压缩到10G左右。一般我们这部分数据访问的频率是非常低的)
    (3)创建分区表,防止后续的全表扫描

    二.DIM层和DWD层

    DIM层DWD层需构建维度模型,一般采用星型模型,呈现的状态一般为星座模型。

    维度建模一般按照以下四个步骤:选择业务过程→声明粒度→确认维度→确认事实

    (1)选择业务过程:在业务系统中,挑选我们感兴趣的业务线。

    (2)声明粒度:数据粒度指数据仓库的数据中保存数据的细化程度或综合程度的级别。声明粒度意味着精确定义事实表中的一行数据表示什么,应该尽可能选择最小粒度,以此来应各种各样的需求。粒度粗,数据量小,统计信息就是不会那么细的。粒度细,数据量大,统计的信息就是会非常的多。

    (3)确认维度:维度的主要作用是描述业务是事实,主要表示的是“谁,何处,何时”等信息。确定维度的原则是:后续需求中是否要分析相关维度的指标。例如,需要统计,什么时间下的订单多,哪个地区下的订单多,哪个用户下的订单多。需要确定的维度就包括:时间维度、地区维度、用户维度。

    (4)确定事实:此处的“事实”一词,指的是业务中的度量值(次数、个数、件数、金额,可以进行累加),例如订单金额、下单次数等。在DWD层,以业务过程为建模驱动,基于每个具体业务过程的特点,构建最细粒度的明细层事实表。事实表可做适当的宽表化处理。

    上面的过程就是比较绕的,过程但是容易理解的。

    事实表\维度

    时间

    用户

    地区

    商品

    优惠券

    活动

    度量值

    订单

    运费/优惠金额/原始金额/最终金额

    订单详情

    件数/优惠金额/原始金额/最终金额

    支付

    支付金额

    加购

    件数/金额

    收藏

    次数

    评价

    次数

    退单

    件数/金额

    退款

    件数/金额

    优惠券领用

    次数

    由上面的表可以得知,事实表存在,不一定有相应的维度对应。优惠券和活动关联到的事实表是比较少的。
    数据仓库的维度建模已经完毕,DWD层是以业务过程为驱动。
    DWS层、DWT层和ADS层都是以需求为驱动,和维度建模已经没有关系了。
    DWS和DWT都是建宽表,按照主题去建表。主题相当于观察问题的角度。对应着维度表。

    三.DWS层与DWT层

    对于上面的维度可以进行两个两个组合啥的,进而得到最终的结果。

    DWS层和DWT层统称宽表层,这两层的设计思想大致相同,通过以下案例进行阐述。
    1)问题引出:两个需求,统计每个省份订单的个数、统计每个省份订单的总金额
    2)处理办法:都是将省份表和订单表进行join,group by省份,然后计算。同样数据被计算了两次,实际上类似的场景还会更多。

    那怎么设计能避免重复计算呢?

    针对上述场景,可以设计一张地区宽表,其主键为地区ID,字段包含为:下单次数、下单金额、支付次数、支付金额等。上述所有指标都统一进行计算,并将结果保存在该宽表中,这样就能有效避免数据的重复计算。

    DWS层是每天,DWT是迄今为止。 

    十二.Hive搭建

    一.架构说明

    Hive引擎包括:默认MR(每执行一次map reduce就是要落一次盘)、tez(有向图进行计算,理解为弱化版的spark)、spark(可以是map map ,然后再进行reduce)

    Hive on Spark:Hive既作为存储元数据又负责SQL的解析优化,语法是HQL语法,执行引擎变成了Spark,Spark负责采用RDD执行。本质是hive,但是执行的引擎是spark,速度是比较快的。(原来是MR)------ 这里我们使用的是

    Spark on Hive : Hive只作为存储元数据,Spark负责SQL解析优化,语法是Spark SQL语法。

    二.hive配置

    懵了(看的课程没有对应上,重新查找课程)
    面试问题:你在开发的时候有没有遇到版本兼容问题?经常会问
    后面是如何配置会说

    十三.HiveOnSpark搭建

    一.上传包

    $ cd /opt/software --- 上传自己的两个jar包

    $ tar -zxvf spark-3.0.0-bin-hadoop3.2.tgz -C /opt/module/
    $ mv spark-3.0.0-bin-hadoop3.2/ spark

    二.配置spark的环境变量
    $ sudo vim /etc/profile.d/my_env.sh

    1. # SPARK_HOME
    2. export SPARK_HOME=/opt/module/spark
    3. export PATH=$PATH:$SPARK_HOME/bin

    $ source /etc/profile.d/my_env.sh

    三.新建spark配置文件,因为我们这里使用的是hive on spark
    $ vim /opt/module/hive/conf/spark-defaults.conf

    1. spark.master yarn
    2. spark.eventLog.enabled true
    3. spark.eventLog.dir hdfs://hadoop102:8020/spark-history
    4. spark.executor.memory 1g
    5. spark.driver.memory 1g

    创建一个存放日志的东西:$  hadoop fs -mkdir /spark-history

    四.向HDFS上传Spark纯净版jar包

    说明1:由于Spark3.0.0非纯净版默认支持的是hive2.3.7版本,直接使用会和安装的Hive3.1.2出现兼容性问题。所以采用Spark纯净版jar包,不包含hadoop和hive相关依赖,避免冲突。

    说明2:Hive任务最终由Spark来执行,Spark任务资源分配由Yarn来调度,该任务有可能被分配到集群的任何一个节点。所以需要将Spark的依赖上传到HDFS集群路径,这样集群中任何一个节点都能获取到。

    (1)上传并解压spark-3.0.0-bin-without-hadoop.tgz
    [atguigu@hadoop102 software]$ tar -zxvf /opt/software/spark-3.0.0-bin-without-hadoop.tgz 
    (2)上传Spark纯净版jar包到HDFS
    [atguigu@hadoop102 software]$ hadoop fs -mkdir /spark-jars
    [atguigu@hadoop102 software]$ hadoop fs -put spark-3.0.0-bin-without-hadoop/jars/* /spark-jars
    讲上述的所有的解压之后的东西进行上传.

    五.修改hive-site.xml文件 --- 真正的将hive和spark进行关联

    [atguigu@hadoop102 software]$ vim /opt/module/hive/conf/hive-site.xml

    1. <!--Spark依赖位置(注意:端口号8020必须和namenode的端口号一致)-->
    2. <property>
    3. <name>spark.yarn.jars</name>
    4. <value>hdfs://hadoop102:8020/spark-jars/*</value>
    5. </property>
    6. <!--Hive执行引擎-->
    7. <property>
    8. <name>hive.execution.engine</name>
    9. <value>spark</value>
    10. </property>
    11. <!--Hive和Spark连接超时时间,电脑比较好就不用改-->
    12. <property>
    13. <name>hive.spark.client.connect.timeout</name>
    14. <value>10000ms</value>
    15. </property>

    注意:hive.spark.client.connect.timeout的默认值是1000ms,如果执行hive的insert语句时,抛如下异常,可以调大该参数到10000ms
    FAILED: SemanticException Failed to get a spark session: org.apache.hadoop.hive.ql.metadata.HiveException: Failed to create Spark client for Spark session d9e0224c-3d14-4bf4-95bc-ee3ec56df48e

    六.Hive on Spark测试

    (1)启动hive客户端

    [atguigu@hadoop102 hive]$ bin/hive

    (2)创建一张测试表

    hive (default)> create table student(id int, name string);

    (3)通过insert测试效果

    hive (default)> insert into table student values(1,'abc');

    若结果如下,则说明配置成功

    我的电脑耗费的时间很多. 但是运行成功了. 家境贫寒,换不起电脑.

     为什么这个地方还是卡着的? 
    再次执行一个任务
    [atguigu@hadoop102 software]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi 1 1 

    关闭第一个任务,可以观察到如下的现象.

    上面现象说明还开启spark,开启MR,MR就会进入等待的状态,但是当将spark进行关闭的时候,MR就是可以开始正常运行.------说明这里的并发度是不可以的
    解决方式:1.增加ApplicationMaster资源比例 

    容量调度器对每个资源队列中同时运行的Application Master占用的资源进行了限制,该限制通过yarn.scheduler.capacity.maximum-am-resource-percent参数实现,其默认值是0.1,表示每个资源队列上Application Master最多可使用的资源为该队列总资源的10%,目的是防止大部分资源都被Application Master占用,而导致Map/Reduce Task无法执行。

    生产环境该参数可使用默认值。但学习环境,集群资源总数很少,如果只分配10%的资源给Application Master,则可能出现,同一时刻只能运行一个Job的情况,因为一个Application Master使用的资源就可能已经达到10%的上限了。故此处可将该值适当调大。

    1)修改配置
    $ vim /opt/module/hadoop-3.1.3/etc/hadoop/capacity-scheduler.xml

    2)对于上面的数值可以进行更改.对于上面配置进行分发
    [atguigu@hadoop102 hadoop]$ rsync.sh capacity-scheduler.xml 

    3)关闭正在运行的任务,重新启动yarn集

    可以观察到这样的情况是正常的.MR是能够执行完成的,但是hive是没有关掉,当关掉的时候才能够执行完成.

    2.创建多个队列,比如增加一个hive队列 

    十四.创建多队列的好处

    增加Yarn容量调度器队列,也可以增加容量调度器的并发度.
    按照计算引擎创建队列:hive spark flink
    按照业务创建队列:下单 支付 点赞 评论 收藏(用户 活动等)
    不创建多个队列时候,就是在一个default之中执行.

    有什么好处?
    (1)假如公司来了一个菜鸟,写了一个死循环,公司资源耗尽,大数据全部瘫痪.---解耦
    (2)假如双11数据量是非常大的,任务是非常的多,如果所有的任务都参与执行,一定是执行不完的,怎么办?将任务分为几个优先级,---支持降级运行 下单(必须完成) - 支付(必须完成) - 点赞(不完成也是可以的) - 评论 - 收藏

    十五.创建hive队列

    还是进入到刚才修改的配置文件之中添加hive选项

     将文件之中的值修改为50

    同时要给队列增加如下新的一些属性:
    这里的配置过程和文件之中default的默认配置是相同的,就是需要进行理解与消化.

    最大容量的含义就是当default是不够的时候,需要使用hive进行.

    将上述的文件进行改正与保存之后,进行同步的分发,重启yarn.有钱就是换64G2T的电脑,努力吧.(吐槽一下)
    重新开启hive,进行插入方式.

    开启成功.再次进行执行如下的代码:
    [atguigu@hadoop102 hadoop]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi 1 1 
    卡死,原因?

    由调度起可以知道,没有给到hive的机会,因此,这里我们是要进行指定hive进行工作的.
    [atguigu@hadoop102 hadoop]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi -Dmapreduce.job.queuename=hive 1 1 
    可以见到这里的hive就是非常正常的了.

    十六.datagrip工具安装

    真无语,找了半天找不到破解文件,咋那莫多的钓鱼网站,浪费了好长时间.国内学术为啥那么不真诚........
    首先进入网站:其他版本 - DataGrip

    安装破解:
    链接:https://pan.baidu.com/s/1Z86cQkbN8Aref8hvsmG-GQ?pwd=1111 
    提取码:1111  ---具体方法看里面的txt文件,比较好操作。

    打开已经安装好的软件,将其进行连接hive。

    上述之中在进行Test之前是需要进行连接hiveserver2的。
    $ hiveserver2

    至少出现四条数据的时候,进行数据库的连接.

    上面是进行数据库连接成功的画面.

    十七.ODS层用户行为日志(建表+加载数据) 

    要求:保持原有的数据,分区不发生改变,lzo压缩.
    创建表
    1.如果要创建的表已经存在,是要删除掉这个表;
    drop table if exists ods_log;
    2.创建外部表
    什么时候创建外部表? 在数据仓库之中,绝大多数都是外部表,只有自己临时使用的表示内部表.
    删除数据:元数据 原始数据,   内部表删除数据: 元数据 原始数据,   外部表删除数据:元数据
    CREATE EXTERNAL TABLE ods_log(line string) 
    3.按照表的日期进行分区
    PARTITIONED BY (`dt` string)
    4.LZO压缩格式处理
    说明Hive的LZO压缩:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+LZO
    5.设置数据存储位置
    LOCATION `/warehouse/gmall/ods/ods_log`;

    1. CREATE EXTERNAL TABLE ods_log (`line` string)
    2. PARTITIONED BY (`dt` string) -- 按照时间创建分区
    3. STORED AS
    4. INPUTFORMAT
    5. "com.hadoop.mapred.DeprecatedLzoTextInputFormat"
    6. OUTPUTFORMAT
    7. "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"
    8. LOCATION
    9. '/warehouse/gmall/ods/ods_log' -- 指定数据在hdfs上的存储位置
    10. ;

    上面的代码我组合了好多次,都是存在问题的,因此,就看最后这一个黑框框之中的就可以.

    加载数据

    在进行加载数据之前我发现我的电脑之中并没有相关的数据.

    首先将之前改的压缩过程,重新变成lzop压缩,具体的过程见第六节。
    如何生成相应的6月14号的数据呢?见下面的操作
    我发现这个地方就是我的第二层flume没有进行配置,就是导致这个数据没有生成的原因.(先去配置第二层的flume)
    这个地方调了一下午,最终第一层是没有问题了,开始调制第二层,就是配置了很多遍总数存在问题,但是最终终于出来了.(耗费了很长时间,里面我也不知道出现了什么错误,就是解决不了,只能是把环境删除之后,重新进行配置)

    这个地方的东西就是我想要的数据,最后终于啊是出来了.(真的是捣鼓了半天)

    数据加载成功.

    发现原来的在2020-06-14日的数据没了,这个数据就是到了下面图片的地方就是一个进行加载移动的过程.

    加载脚本的定义:
     $ vim hdfs_to_ods_log.sh

    1. #!/bin/bash
    2. # 定义变量方便修改
    3. APP=gmall
    4. hive=/opt/module/hive/bin/hive
    5. hadoop=/opt/module/hadoop-3.1.3/bin/hadoop
    6. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    7. if [ -n "$1" ] ;then
    8. do_date=$1
    9. else
    10. do_date=`date -d "-1 day" +%F`
    11. fi
    12. echo ================== 日志日期为 $do_date ==================
    13. sql="
    14. load data inpath '/origin_data/$APP/log/topic_log/$do_date' into table ${APP}.ods_log partition(dt='$do_date');
    15. "
    16. $hive -e "$sql"

    $ chmod 777 hdfs_to_ods_log.sh
    $ hdfs_to_ods_log.sh 2020-06-15
    上面是进行将2020-06-15日的数据进行导入的过程,但是我不知道为什么有的时候会导入不成功需要重新导入.

    十八.脚本之中单引号和双引号之间的区别

    $ vim test.sh

    1. #!/bin/bash
    2. do_date=$1
    3. echo '$do_date'
    4. echo "$do_date"
    5. echo "'$do_date'"
    6. echo '"$do_date"'
    7. echo `date`

    (1)单引号不取变量值
    (2)双引号取变量值
    (3)反引号`,执行引号中命令
    (4)双引号内部嵌套单引号,取出变量值
    (5)单引号内部嵌套双引号,不取出变量值

     十九.ODS_业务数据建表

    将上述数据导入hive之中。 

    上述过程之中\t是不可以被省略的。
    ODS层业务数据建表

    1. --ods层业务数据页面
    2. --3.3.1 订单表(增量及更新)
    3. --hive (gmall)>
    4. drop table if exists ods_order_info;
    5. create external table ods_order_info (
    6. `id` string COMMENT '订单号',
    7. `final_total_amount` decimal(16,2) COMMENT '订单金额',
    8. `order_status` string COMMENT '订单状态',
    9. `user_id` string COMMENT '用户id',
    10. `out_trade_no` string COMMENT '支付流水号',
    11. `create_time` string COMMENT '创建时间',
    12. `operate_time` string COMMENT '操作时间',
    13. `province_id` string COMMENT '省份ID',
    14. `benefit_reduce_amount` decimal(16,2) COMMENT '优惠金额',
    15. `original_total_amount` decimal(16,2) COMMENT '原价金额',
    16. `feight_fee` decimal(16,2) COMMENT '运费'
    17. ) COMMENT '订单表'
    18. PARTITIONED BY (`dt` string) -- 按照时间创建分区
    19. row format delimited fields terminated by '\t' -- 指定分割符为\t
    20. STORED AS -- 指定存储方式,读数据采用LzoTextInputFormat;输出数据采用TextOutputFormat
    21. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    22. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    23. location '/warehouse/gmall/ods/ods_order_info/' -- 指定数据在hdfs上的存储位置
    24. ;
    25. --3.3.2 订单详情表(增量)
    26. --hive (gmall)>
    27. drop table if exists ods_order_detail;
    28. create external table ods_order_detail(
    29. `id` string COMMENT '编号',
    30. `order_id` string COMMENT '订单号',
    31. `user_id` string COMMENT '用户id',
    32. `sku_id` string COMMENT '商品id',
    33. `sku_name` string COMMENT '商品名称',
    34. `order_price` decimal(16,2) COMMENT '商品价格',
    35. `sku_num` bigint COMMENT '商品数量',
    36. `create_time` string COMMENT '创建时间',
    37. `source_type` string COMMENT '来源类型',
    38. `source_id` string COMMENT '来源编号'
    39. ) COMMENT '订单详情表'
    40. PARTITIONED BY (`dt` string)
    41. row format delimited fields terminated by '\t'
    42. STORED AS
    43. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    44. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    45. location '/warehouse/gmall/ods/ods_order_detail/';
    46. --3.3.3 SKU商品表(全量)
    47. --hive (gmall)>
    48. drop table if exists ods_sku_info;
    49. create external table ods_sku_info(
    50. `id` string COMMENT 'skuId',
    51. `spu_id` string COMMENT 'spuid',
    52. `price` decimal(16,2) COMMENT '价格',
    53. `sku_name` string COMMENT '商品名称',
    54. `sku_desc` string COMMENT '商品描述',
    55. `weight` string COMMENT '重量',
    56. `tm_id` string COMMENT '品牌id',
    57. `category3_id` string COMMENT '品类id',
    58. `create_time` string COMMENT '创建时间'
    59. ) COMMENT 'SKU商品表'
    60. PARTITIONED BY (`dt` string)
    61. row format delimited fields terminated by '\t'
    62. STORED AS
    63. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    64. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    65. location '/warehouse/gmall/ods/ods_sku_info/';
    66. --3.3.4 用户表(增量及更新)
    67. --hive (gmall)>
    68. drop table if exists ods_user_info;
    69. create external table ods_user_info(
    70. `id` string COMMENT '用户id',
    71. `name` string COMMENT '姓名',
    72. `birthday` string COMMENT '生日',
    73. `gender` string COMMENT '性别',
    74. `email` string COMMENT '邮箱',
    75. `user_level` string COMMENT '用户等级',
    76. `create_time` string COMMENT '创建时间',
    77. `operate_time` string COMMENT '操作时间'
    78. ) COMMENT '用户表'
    79. PARTITIONED BY (`dt` string)
    80. row format delimited fields terminated by '\t'
    81. STORED AS
    82. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    83. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    84. location '/warehouse/gmall/ods/ods_user_info/';
    85. --3.3.5 商品一级分类表(全量)
    86. --hive (gmall)>
    87. drop table if exists ods_base_category1;
    88. create external table ods_base_category1(
    89. `id` string COMMENT 'id',
    90. `name` string COMMENT '名称'
    91. ) COMMENT '商品一级分类表'
    92. PARTITIONED BY (`dt` string)
    93. row format delimited fields terminated by '\t'
    94. STORED AS
    95. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    96. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    97. location '/warehouse/gmall/ods/ods_base_category1/';
    98. --3.3.6 商品二级分类表(全量)
    99. --hive (gmall)>
    100. drop table if exists ods_base_category2;
    101. create external table ods_base_category2(
    102. `id` string COMMENT ' id',
    103. `name` string COMMENT '名称',
    104. category1_id string COMMENT '一级品类id'
    105. ) COMMENT '商品二级分类表'
    106. PARTITIONED BY (`dt` string)
    107. row format delimited fields terminated by '\t'
    108. STORED AS
    109. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    110. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    111. location '/warehouse/gmall/ods/ods_base_category2/';
    112. --3.3.7 商品三级分类表(全量)
    113. --hive (gmall)>
    114. drop table if exists ods_base_category3;
    115. create external table ods_base_category3(
    116. `id` string COMMENT ' id',
    117. `name` string COMMENT '名称',
    118. category2_id string COMMENT '二级品类id'
    119. ) COMMENT '商品三级分类表'
    120. PARTITIONED BY (`dt` string)
    121. row format delimited fields terminated by '\t'
    122. STORED AS
    123. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    124. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    125. location '/warehouse/gmall/ods/ods_base_category3/';
    126. --3.3.8 支付流水表(增量)
    127. --hive (gmall)>
    128. drop table if exists ods_payment_info;
    129. create external table ods_payment_info(
    130. `id` bigint COMMENT '编号',
    131. `out_trade_no` string COMMENT '对外业务编号',
    132. `order_id` string COMMENT '订单编号',
    133. `user_id` string COMMENT '用户编号',
    134. `alipay_trade_no` string COMMENT '支付宝交易流水编号',
    135. `total_amount` decimal(16,2) COMMENT '支付金额',
    136. `subject` string COMMENT '交易内容',
    137. `payment_type` string COMMENT '支付类型',
    138. `payment_time` string COMMENT '支付时间'
    139. ) COMMENT '支付流水表'
    140. PARTITIONED BY (`dt` string)
    141. row format delimited fields terminated by '\t'
    142. STORED AS
    143. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    144. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    145. location '/warehouse/gmall/ods/ods_payment_info/';
    146. --3.3.9 省份表(特殊)
    147. --hive (gmall)>
    148. drop table if exists ods_base_province;
    149. create external table ods_base_province (
    150. `id` bigint COMMENT '编号',
    151. `name` string COMMENT '省份名称',
    152. `region_id` string COMMENT '地区ID',
    153. `area_code` string COMMENT '地区编码',
    154. `iso_code` string COMMENT 'iso编码,superset可视化使用'
    155. ) COMMENT '省份表'
    156. row format delimited fields terminated by '\t'
    157. STORED AS
    158. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    159. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    160. location '/warehouse/gmall/ods/ods_base_province/';
    161. --3.3.10 地区表(特殊)
    162. --hive (gmall)>
    163. drop table if exists ods_base_region;
    164. create external table ods_base_region (
    165. `id` string COMMENT '编号',
    166. `region_name` string COMMENT '地区名称'
    167. ) COMMENT '地区表'
    168. row format delimited fields terminated by '\t'
    169. STORED AS
    170. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    171. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    172. location '/warehouse/gmall/ods/ods_base_region/';
    173. --3.3.11 品牌表(全量)
    174. --hive (gmall)>
    175. drop table if exists ods_base_trademark;
    176. create external table ods_base_trademark (
    177. `tm_id` string COMMENT '编号',
    178. `tm_name` string COMMENT '品牌名称'
    179. ) COMMENT '品牌表'
    180. PARTITIONED BY (`dt` string)
    181. row format delimited fields terminated by '\t'
    182. STORED AS
    183. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    184. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    185. location '/warehouse/gmall/ods/ods_base_trademark/';
    186. --3.3.12 订单状态表(增量)
    187. --hive (gmall)>
    188. drop table if exists ods_order_status_log;
    189. create external table ods_order_status_log (
    190. `id` string COMMENT '编号',
    191. `order_id` string COMMENT '订单ID',
    192. `order_status` string COMMENT '订单状态',
    193. `operate_time` string COMMENT '修改时间'
    194. ) COMMENT '订单状态表'
    195. PARTITIONED BY (`dt` string)
    196. row format delimited fields terminated by '\t'
    197. STORED AS
    198. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    199. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    200. location '/warehouse/gmall/ods/ods_order_status_log/';
    201. --3.3.13 SPU商品表(全量)
    202. --hive (gmall)>
    203. drop table if exists ods_spu_info;
    204. create external table ods_spu_info(
    205. `id` string COMMENT 'spuid',
    206. `spu_name` string COMMENT 'spu名称',
    207. `category3_id` string COMMENT '品类id',
    208. `tm_id` string COMMENT '品牌id'
    209. ) COMMENT 'SPU商品表'
    210. PARTITIONED BY (`dt` string)
    211. row format delimited fields terminated by '\t'
    212. STORED AS
    213. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    214. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    215. location '/warehouse/gmall/ods/ods_spu_info/';
    216. --3.3.14 商品评论表(增量)
    217. --hive (gmall)>
    218. drop table if exists ods_comment_info;
    219. create external table ods_comment_info(
    220. `id` string COMMENT '编号',
    221. `user_id` string COMMENT '用户ID',
    222. `sku_id` string COMMENT '商品sku',
    223. `spu_id` string COMMENT '商品spu',
    224. `order_id` string COMMENT '订单ID',
    225. `appraise` string COMMENT '评价',
    226. `create_time` string COMMENT '评价时间'
    227. ) COMMENT '商品评论表'
    228. PARTITIONED BY (`dt` string)
    229. row format delimited fields terminated by '\t'
    230. STORED AS
    231. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    232. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    233. location '/warehouse/gmall/ods/ods_comment_info/';
    234. --3.3.15 退单表(增量)
    235. --hive (gmall)>
    236. drop table if exists ods_order_refund_info;
    237. create external table ods_order_refund_info(
    238. `id` string COMMENT '编号',
    239. `user_id` string COMMENT '用户ID',
    240. `order_id` string COMMENT '订单ID',
    241. `sku_id` string COMMENT '商品ID',
    242. `refund_type` string COMMENT '退款类型',
    243. `refund_num` bigint COMMENT '退款件数',
    244. `refund_amount` decimal(16,2) COMMENT '退款金额',
    245. `refund_reason_type` string COMMENT '退款原因类型',
    246. `create_time` string COMMENT '退款时间'
    247. ) COMMENT '退单表'
    248. PARTITIONED BY (`dt` string)
    249. row format delimited fields terminated by '\t'
    250. STORED AS
    251. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    252. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    253. location '/warehouse/gmall/ods/ods_order_refund_info/';
    254. --3.3.16 加购表(全量)
    255. --hive (gmall)>
    256. drop table if exists ods_cart_info;
    257. create external table ods_cart_info(
    258. `id` string COMMENT '编号',
    259. `user_id` string COMMENT '用户id',
    260. `sku_id` string COMMENT 'skuid',
    261. `cart_price` decimal(16,2) COMMENT '放入购物车时价格',
    262. `sku_num` bigint COMMENT '数量',
    263. `sku_name` string COMMENT 'sku名称 (冗余)',
    264. `create_time` string COMMENT '创建时间',
    265. `operate_time` string COMMENT '修改时间',
    266. `is_ordered` string COMMENT '是否已经下单',
    267. `order_time` string COMMENT '下单时间',
    268. `source_type` string COMMENT '来源类型',
    269. `source_id` string COMMENT '来源编号'
    270. ) COMMENT '加购表'
    271. PARTITIONED BY (`dt` string)
    272. row format delimited fields terminated by '\t'
    273. STORED AS
    274. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    275. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    276. location '/warehouse/gmall/ods/ods_cart_info/';
    277. --3.3.17 商品收藏表(全量)
    278. --hive (gmall)>
    279. drop table if exists ods_favor_info;
    280. create external table ods_favor_info(
    281. `id` string COMMENT '编号',
    282. `user_id` string COMMENT '用户id',
    283. `sku_id` string COMMENT 'skuid',
    284. `spu_id` string COMMENT 'spuid',
    285. `is_cancel` string COMMENT '是否取消',
    286. `create_time` string COMMENT '收藏时间',
    287. `cancel_time` string COMMENT '取消时间'
    288. ) COMMENT '商品收藏表'
    289. PARTITIONED BY (`dt` string)
    290. row format delimited fields terminated by '\t'
    291. STORED AS
    292. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    293. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    294. location '/warehouse/gmall/ods/ods_favor_info/';
    295. --3.3.18 优惠券领用表(新增及变化)
    296. --hive (gmall)>
    297. drop table if exists ods_coupon_use;
    298. create external table ods_coupon_use(
    299. `id` string COMMENT '编号',
    300. `coupon_id` string COMMENT '优惠券ID',
    301. `user_id` string COMMENT 'skuid',
    302. `order_id` string COMMENT 'spuid',
    303. `coupon_status` string COMMENT '优惠券状态',
    304. `get_time` string COMMENT '领取时间',
    305. `using_time` string COMMENT '使用时间(下单)',
    306. `used_time` string COMMENT '使用时间(支付)'
    307. ) COMMENT '优惠券领用表'
    308. PARTITIONED BY (`dt` string)
    309. row format delimited fields terminated by '\t'
    310. STORED AS
    311. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    312. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    313. location '/warehouse/gmall/ods/ods_coupon_use/';
    314. --3.3.19 优惠券表(全量)
    315. --hive (gmall)>
    316. drop table if exists ods_coupon_info;
    317. create external table ods_coupon_info(
    318. `id` string COMMENT '购物券编号',
    319. `coupon_name` string COMMENT '购物券名称',
    320. `coupon_type` string COMMENT '购物券类型 1 现金券 2 折扣券 3 满减券 4 满件打折券',
    321. `condition_amount` decimal(16,2) COMMENT '满额数',
    322. `condition_num` bigint COMMENT '满件数',
    323. `activity_id` string COMMENT '活动编号',
    324. `benefit_amount` decimal(16,2) COMMENT '减金额',
    325. `benefit_discount` decimal(16,2) COMMENT '折扣',
    326. `create_time` string COMMENT '创建时间',
    327. `range_type` string COMMENT '范围类型 1、商品 2、品类 3、品牌',
    328. `spu_id` string COMMENT '商品id',
    329. `tm_id` string COMMENT '品牌id',
    330. `category3_id` string COMMENT '品类id',
    331. `limit_num` bigint COMMENT '最多领用次数',
    332. `operate_time` string COMMENT '修改时间',
    333. `expire_time` string COMMENT '过期时间'
    334. ) COMMENT '优惠券表'
    335. PARTITIONED BY (`dt` string)
    336. row format delimited fields terminated by '\t'
    337. STORED AS
    338. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    339. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    340. location '/warehouse/gmall/ods/ods_coupon_info/';
    341. --3.3.20 活动表(全量)
    342. --hive (gmall)>
    343. drop table if exists ods_activity_info;
    344. create external table ods_activity_info(
    345. `id` string COMMENT '编号',
    346. `activity_name` string COMMENT '活动名称',
    347. `activity_type` string COMMENT '活动类型',
    348. `start_time` string COMMENT '开始时间',
    349. `end_time` string COMMENT '结束时间',
    350. `create_time` string COMMENT '创建时间'
    351. ) COMMENT '活动表'
    352. PARTITIONED BY (`dt` string)
    353. row format delimited fields terminated by '\t'
    354. STORED AS
    355. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    356. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    357. location '/warehouse/gmall/ods/ods_activity_info/';
    358. --3.3.21 活动订单关联表(增量)
    359. --hive (gmall)>
    360. drop table if exists ods_activity_order;
    361. create external table ods_activity_order(
    362. `id` string COMMENT '编号',
    363. `activity_id` string COMMENT '优惠券ID',
    364. `order_id` string COMMENT 'skuid',
    365. `create_time` string COMMENT '领取时间'
    366. ) COMMENT '活动订单关联表'
    367. PARTITIONED BY (`dt` string)
    368. row format delimited fields terminated by '\t'
    369. STORED AS
    370. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    371. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    372. location '/warehouse/gmall/ods/ods_activity_order/';
    373. --3.3.22 优惠规则表(全量)
    374. --hive (gmall)>
    375. drop table if exists ods_activity_rule;
    376. create external table ods_activity_rule(
    377. `id` string COMMENT '编号',
    378. `activity_id` string COMMENT '活动ID',
    379. `condition_amount` decimal(16,2) COMMENT '满减金额',
    380. `condition_num` bigint COMMENT '满减件数',
    381. `benefit_amount` decimal(16,2) COMMENT '优惠金额',
    382. `benefit_discount` decimal(16,2) COMMENT '优惠折扣',
    383. `benefit_level` string COMMENT '优惠级别'
    384. ) COMMENT '优惠规则表'
    385. PARTITIONED BY (`dt` string)
    386. row format delimited fields terminated by '\t'
    387. STORED AS
    388. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    389. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    390. location '/warehouse/gmall/ods/ods_activity_rule/';
    391. --3.3.23 编码字典表(全量)
    392. --hive (gmall)>
    393. drop table if exists ods_base_dic;
    394. create external table ods_base_dic(
    395. `dic_code` string COMMENT '编号',
    396. `dic_name` string COMMENT '编码名称',
    397. `parent_code` string COMMENT '父编码',
    398. `create_time` string COMMENT '创建日期',
    399. `operate_time` string COMMENT '操作日期'
    400. ) COMMENT '编码字典表'
    401. PARTITIONED BY (`dt` string)
    402. row format delimited fields terminated by '\t'
    403. STORED AS
    404. INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
    405. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    406. location '/warehouse/gmall/ods/ods_base_dic/';

    加载完成。

    二十.ODS_业务数据脚本

    $ vim hdfs_to_ods_db.sh

    1. #!/bin/bash
    2. APP=gmall
    3. hive=/opt/module/hive/bin/hive
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$2" ] ;then
    6. do_date=$2
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql1="
    11. load data inpath '/origin_data/$APP/db/order_info/$do_date' OVERWRITE into table ${APP}.ods_order_info partition(dt='$do_date');
    12. load data inpath '/origin_data/$APP/db/order_detail/$do_date' OVERWRITE into table ${APP}.ods_order_detail partition(dt='$do_date');
    13. load data inpath '/origin_data/$APP/db/sku_info/$do_date' OVERWRITE into table ${APP}.ods_sku_info partition(dt='$do_date');
    14. load data inpath '/origin_data/$APP/db/user_info/$do_date' OVERWRITE into table ${APP}.ods_user_info partition(dt='$do_date');
    15. load data inpath '/origin_data/$APP/db/payment_info/$do_date' OVERWRITE into table ${APP}.ods_payment_info partition(dt='$do_date');
    16. load data inpath '/origin_data/$APP/db/base_category1/$do_date' OVERWRITE into table ${APP}.ods_base_category1 partition(dt='$do_date');
    17. load data inpath '/origin_data/$APP/db/base_category2/$do_date' OVERWRITE into table ${APP}.ods_base_category2 partition(dt='$do_date');
    18. load data inpath '/origin_data/$APP/db/base_category3/$do_date' OVERWRITE into table ${APP}.ods_base_category3 partition(dt='$do_date');
    19. load data inpath '/origin_data/$APP/db/base_trademark/$do_date' OVERWRITE into table ${APP}.ods_base_trademark partition(dt='$do_date');
    20. load data inpath '/origin_data/$APP/db/activity_info/$do_date' OVERWRITE into table ${APP}.ods_activity_info partition(dt='$do_date');
    21. load data inpath '/origin_data/$APP/db/activity_order/$do_date' OVERWRITE into table ${APP}.ods_activity_order partition(dt='$do_date');
    22. load data inpath '/origin_data/$APP/db/cart_info/$do_date' OVERWRITE into table ${APP}.ods_cart_info partition(dt='$do_date');
    23. load data inpath '/origin_data/$APP/db/comment_info/$do_date' OVERWRITE into table ${APP}.ods_comment_info partition(dt='$do_date');
    24. load data inpath '/origin_data/$APP/db/coupon_info/$do_date' OVERWRITE into table ${APP}.ods_coupon_info partition(dt='$do_date');
    25. load data inpath '/origin_data/$APP/db/coupon_use/$do_date' OVERWRITE into table ${APP}.ods_coupon_use partition(dt='$do_date');
    26. load data inpath '/origin_data/$APP/db/favor_info/$do_date' OVERWRITE into table ${APP}.ods_favor_info partition(dt='$do_date');
    27. load data inpath '/origin_data/$APP/db/order_refund_info/$do_date' OVERWRITE into table ${APP}.ods_order_refund_info partition(dt='$do_date');
    28. load data inpath '/origin_data/$APP/db/order_status_log/$do_date' OVERWRITE into table ${APP}.ods_order_status_log partition(dt='$do_date');
    29. load data inpath '/origin_data/$APP/db/spu_info/$do_date' OVERWRITE into table ${APP}.ods_spu_info partition(dt='$do_date');
    30. load data inpath '/origin_data/$APP/db/activity_rule/$do_date' OVERWRITE into table ${APP}.ods_activity_rule partition(dt='$do_date');
    31. load data inpath '/origin_data/$APP/db/base_dic/$do_date' OVERWRITE into table ${APP}.ods_base_dic partition(dt='$do_date');
    32. "
    33. sql2="
    34. load data inpath '/origin_data/$APP/db/base_province/$do_date' OVERWRITE into table ${APP}.ods_base_province;
    35. load data inpath '/origin_data/$APP/db/base_region/$do_date' OVERWRITE into table ${APP}.ods_base_region;
    36. "
    37. case $1 in
    38. "first"){
    39. $hive -e "$sql1$sql2"
    40. };;
    41. "all"){
    42. $hive -e "$sql1"
    43. };;
    44. esac

    注意上面的sql2,它是一般只加载一次的.

    1)初次导入

    初次导入时,脚本的第一个参数应为first,线上环境不传第二个参数,自动获取前一天日期
    $ hdfs_to_ods_db.sh first 2020-06-14

    2)每日导入

    每日重复导入,脚本的第一个参数应为all,线上环境不传第二个参数,自动获取前一天日期。
    $ hdfs_to_ods_db.sh all 2020-06-15

    spark3.0.0 => hive2.3.7 =>hadoop2.0
    hive3.1.2 => spark2.4.5(不行,改为spark3.0-纯净版) =>hadoop3.0以上,hive和hadoop对应

    要使用纯净版的spark,为什么还要上传非纯净版的spark?
    纯净版的spark用来放到yarn上面进行计算.
    非纯净版的spark,用来hive通信,创建spark session会话.

    二十一.ODS_索引问题

    在原来的hdfs_***_log.sh后面增加如下所示:


    $ [hadoop-3.1.3/bin]hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer -Dmapreduce.job.queuename=hive /warehouse/gmall/ods/ods_log/dt=2020-06-14
    $ [hadoop-3.1.3/bin]hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer -Dmapreduce.job.queuename=hive /warehouse/gmall/ods/ods_log/dt=2020-06-15
    上面是进行创建6-14和6-15的索引.

    二十二.DWD层_get_json_object --- 工薪阶层

    1)对用户行为数据解析。
    2)对核心数据进行判空过滤。
    3)对业务数据采用维度模型重新建模。

    页面埋点数据:

    埋点:
    在企业中页面里非常多:(中大型公司)动作 曝光 错误 页面 公共信息
    中小型公司(页面比较少):一个页面一张表 (商品列表 商品点击 广告 故障 后台活跃 通知 点赞 评论 收藏)

     启动日志:

    通过启动日志查看用户是否活跃.

    1)数据

    [{"name":"姚大郎","sex":"男","age":"25"},{"name":"西门庆","sex":"男","age":"47"}]

    2)取出第一个json对象

    hive (gmall)>

    select get_json_object('[{"name":"姚大郎","sex":"男","age":"25"},{"name":"西门庆","sex":"男","age":"47"}]','$[0]'); ---第一个是代表的是要进行处理的对象,$[0]代表是全部对象

    结果是:{"name":"姚大郎","sex":"男","age":"25"}

    3)取出第一个json的age字段的值

    hive (gmall)>

    SELECT get_json_object('[{"name":"姚大郎","sex":"男","age":"25"},{"name":"西门庆","sex":"男","age":"47"}]',"$[0].age");----获取值

    结果是:25
    英年早逝的姚大郎同志,哈哈哈哈哈哈哈哈哈.

    运行示意图:

    上面的这个函数的使用是非常重要的.

    二十三.创建启动日志

    上面的启动日志和事件日志都是存在与ods_log之中.将上面之中的这两个日志进行相应的分离. 

    hive-gmall操作
     

    1. drop table if exists dwd_start_log;
    2. CREATE EXTERNAL TABLE dwd_start_log(
    3. `area_code` string COMMENT '地区编码',
    4. `brand` string COMMENT '手机品牌',
    5. `channel` string COMMENT '渠道',
    6. `model` string COMMENT '手机型号',
    7. `mid_id` string COMMENT '设备id',
    8. `os` string COMMENT '操作系统',
    9. `user_id` string COMMENT '会员id',
    10. `version_code` string COMMENT 'app版本号',
    11. `entry` string COMMENT ' icon手机图标 notice 通知 install 安装后启动',
    12. `loading_time` bigint COMMENT '启动加载时间',
    13. `open_ad_id` string COMMENT '广告页ID ',
    14. `open_ad_ms` bigint COMMENT '广告总共播放时间',
    15. `open_ad_skip_ms` bigint COMMENT '用户跳过广告时点',
    16. `ts` bigint COMMENT '时间'
    17. ) COMMENT '启动日志表'
    18. PARTITIONED BY (dt string) -- 按照时间创建分区
    19. stored as parquet -- 采用parquet列式存储
    20. LOCATION '/warehouse/gmall/dwd/dwd_start_log' -- 指定在HDFS上存储位置
    21. TBLPROPERTIES('parquet.compression'='lzo') -- 采用LZO压缩
    22. ;

    为什么在DWD层采用列式存储,ODS之中的数据是进行load剪切过来的,最原始的数据是在hdfs之中剪切过来的.

    parque进行列式存储:
    列式存储的好处: 

    在进行查询的时候,select name from user(查询速度快);列式存储配合压缩,压缩比会更小,减少磁盘使用空间.

    说明:数据采用parquet存储方式,是可以支持切片的,不需要再对数据创建索引。如果单纯的text方式存储数据,需要采用支持切片的,lzop压缩方式并创建索引。

    二十四.加载数据

    hive
     

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_start_log partition(dt='2020-06-14')
    3. select
    4. get_json_object(line,'$.common.ar'),
    5. get_json_object(line,'$.common.ba'),
    6. get_json_object(line,'$.common.ch'),
    7. get_json_object(line,'$.common.md'),
    8. get_json_object(line,'$.common.mid'),
    9. get_json_object(line,'$.common.os'),
    10. get_json_object(line,'$.common.uid'),
    11. get_json_object(line,'$.common.vc'),
    12. get_json_object(line,'$.start.entry'),
    13. get_json_object(line,'$.start.loading_time'),
    14. get_json_object(line,'$.start.open_ad_id'),
    15. get_json_object(line,'$.start.open_ad_ms'),
    16. get_json_object(line,'$.start.open_ad_skip_ms'),
    17. get_json_object(line,'$.ts')
    18. from ods_log
    19. where dt='2020-06-14'
    20. and get_json_object(line,'$.start') is not null;

    hive (gmall)> select * from dwd_start_log where dt='2020-06-14' limit 2;

    执行是没有问题的. 

    二十五.hive读取文件

    select * from ods_log;---不执行MR

    select count(*) from ods_log;---执行MR


    原因是select * from ods_log不执行MR操作,默认采用的是ods_log建表语句中指定的DeprecatedLzoTextInputFormat,能够识别lzo.index为索引文件。

    select count(*) from ods_log执行MR操作,默认采用的是CombineHiveInputFormat,不能识别lzo.index为索引文件,将索引文件当做普通文件处理。更严重的是,这会导致LZO文件无法切片。

    解决办法:修改CombineHiveInputFormatHiveInputFormat

    再次测试

    hive (gmall)>

    SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;

    hive (gmall)> select * from ods_log;

    Time taken: 0.706 seconds, Fetched: 2955 row(s)

    hive (gmall)> select count(*) from ods_log;

    2955

     二十六.页面日志解析

    1)进行建表

    1. hive (gmall)>
    2. drop table if exists dwd_page_log;
    3. CREATE EXTERNAL TABLE dwd_page_log(
    4. `area_code` string COMMENT '地区编码',
    5. `brand` string COMMENT '手机品牌',
    6. `channel` string COMMENT '渠道',
    7. `model` string COMMENT '手机型号',
    8. `mid_id` string COMMENT '设备id',
    9. `os` string COMMENT '操作系统',
    10. `user_id` string COMMENT '会员id',
    11. `version_code` string COMMENT 'app版本号',
    12. `during_time` bigint COMMENT '持续时间毫秒',
    13. `page_item` string COMMENT '目标id ',
    14. `page_item_type` string COMMENT '目标类型',
    15. `last_page_id` string COMMENT '上页类型',
    16. `page_id` string COMMENT '页面ID ',
    17. `source_type` string COMMENT '来源类型',
    18. `ts` bigint
    19. ) COMMENT '页面日志表'
    20. PARTITIONED BY (dt string)
    21. stored as parquet
    22. LOCATION '/warehouse/gmall/dwd/dwd_page_log'
    23. TBLPROPERTIES('parquet.compression'='lzo');

    2)数据导入

    1. insert overwrite table dwd_page_log partition(dt='2020-06-14')
    2. select
    3. get_json_object(line,'$.common.ar'),
    4. get_json_object(line,'$.common.ba'),
    5. get_json_object(line,'$.common.ch'),
    6. get_json_object(line,'$.common.md'),
    7. get_json_object(line,'$.common.mid'),
    8. get_json_object(line,'$.common.os'),
    9. get_json_object(line,'$.common.uid'),
    10. get_json_object(line,'$.common.vc'),
    11. get_json_object(line,'$.page.during_time'),
    12. get_json_object(line,'$.page.item'),
    13. get_json_object(line,'$.page.item_type'),
    14. get_json_object(line,'$.page.last_page_id'),
    15. get_json_object(line,'$.page.page_id'),
    16. get_json_object(line,'$.page.sourceType'),
    17. get_json_object(line,'$.ts')
    18. from ods_log
    19. where dt='2020-06-14'
    20. and get_json_object(line,'$.page') is not null;

    3)查看数据
     

    1. hive (gmall)>
    2. select * from dwd_page_log where dt='2020-06-14' limit 2;

    二十七.动作日志建表

    动作日志解析思路:动作日志表中每行数据对应用户的一个动作记录,一个动作记录应当包含公共信息、页面信息以及动作信息。先将包含action字段的日志过滤出来,然后通过UDTF函数,将action数组“炸开”(类似于explode函数的效果),然后使用get_json_object函数解析每个字段。

    1)建表语句

    1. hive (gmall)>
    2. drop table if exists dwd_action_log;
    3. CREATE EXTERNAL TABLE dwd_action_log(
    4. `area_code` string COMMENT '地区编码',
    5. `brand` string COMMENT '手机品牌',
    6. `channel` string COMMENT '渠道',
    7. `model` string COMMENT '手机型号',
    8. `mid_id` string COMMENT '设备id',
    9. `os` string COMMENT '操作系统',
    10. `user_id` string COMMENT '会员id',
    11. `version_code` string COMMENT 'app版本号',
    12. `during_time` bigint COMMENT '持续时间毫秒',
    13. `page_item` string COMMENT '目标id ',
    14. `page_item_type` string COMMENT '目标类型',
    15. `last_page_id` string COMMENT '上页类型',
    16. `page_id` string COMMENT '页面id ',
    17. `source_type` string COMMENT '来源类型',
    18. `action_id` string COMMENT '动作id',
    19. `item` string COMMENT '目标id ',
    20. `item_type` string COMMENT '目标类型',
    21. `ts` bigint COMMENT '时间'
    22. ) COMMENT '动作日志表'
    23. PARTITIONED BY (dt string)
    24. stored as parquet
    25. LOCATION '/warehouse/gmall/dwd/dwd_action_log'
    26. TBLPROPERTIES('parquet.compression'='lzo');

    二十八.UDTF函数思想

    2)创建UDTF函数——设计思路(下面的这张表特别需要进行注意)

    3)创建UDTF函数——编写代码

    (1)创建一个maven工程:hivefunction

    电脑炸了! 

    (2)创建包名:com.atguigu.hive.udtf

    3)引入如下依赖

    1. <dependencies>
    2.     <!--添加hive依赖-->
    3.     <dependency>
    4.         <groupId>org.apache.hive</groupId>
    5.         <artifactId>hive-exec</artifactId>
    6.         <version>3.1.2</version>
    7.     </dependency>
    8. </dependencies>

    4)编码

    1. package com.atguigu.hive.udtf;
    2. import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
    3. import org.apache.hadoop.hive.ql.metadata.HiveException;
    4. import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
    5. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
    6. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
    7. import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
    8. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
    9. import org.json.JSONArray;
    10. import java.util.ArrayList;
    11. import java.util.List;
    12. public class ExplodeJSONArray extends GenericUDTF {
    13. @Override
    14. public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
    15. // 1 参数合法性检查:如果要是传入的参数不是一个的话,抛出一个异常 action
    16. if (argOIs.getAllStructFieldRefs().size() != 1){
    17. throw new UDFArgumentException("ExplodeJSONArray 只需要一个参数");
    18. }
    19. // 2 第一个参数必须为string
    20. if(!"string".equals(argOIs.getAllStructFieldRefs().get(0).getFieldObjectInspector().getTypeName())){
    21. throw new UDFArgumentException("json_array_to_struct_array的第1个参数应为string类型");
    22. }
    23. // 3 定义返回值名称和类型
    24. List fieldNames = new ArrayList();
    25. List fieldOIs = new ArrayList();
    26. fieldNames.add("items");//这个名字可以随便起
    27. fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);//校验上面的名称,判断其是不是string类型
    28. return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    29. }
    30. public void process(Object[] objects) throws HiveException {
    31. //object=>aaction => 多进多出(多行进多行出)
    32. // 1 获取传入的数据
    33. String jsonArray = objects[0].toString();
    34. // 2 将string转换为json数组
    35. JSONArray actions = new JSONArray(jsonArray);
    36. // 3 循环一次,取出数组中的一个json,并写出----就是将JSON之中的东西依次进行导出的过程.进行循环遍历,一次一次进行相应的写出
    37. for (int i = 0; i < actions.length(); i++) {
    38. String[] result = new String[1];
    39. result[0] = actions.getString(i);
    40. forward(result);
    41. }
    42. }
    43. public void close() throws HiveException {
    44. }
    45. }

    二十九.DWD_创建永久UDTF函数

    4)创建函数

    (1)打包(package)
    将上面的包进行右键,Show in Explorer.
    (2)将hivefunction-1.0-SNAPSHOT.jar上传到hadoop102的/opt/module,然后再将该jar包上传到HDFS的/user/hive/jars路径下
    [atguigu@hadoop102 module]$ hadoop fs -mkdir -p /user/hive/jars
    [atguigu@hadoop102 module]$ hadoop fs -put hivefunction-1.0-SNAPSHOT.jar /user/hive/jars

    上传成功.

    (3)创建永久函数与开发好的java class关联---下面的explode_json_array是相应的一个函数

    hive (gmall)>

    create function explode_json_array as 'com.atguigu.hive.udtf.ExplodeJSONArray' using jar 'hdfs://hadoop102:8020/user/hive/jars/hivefunction-1.0-SNAPSHOT.jar';

    (4)注意:如果修改了自定义函数重新生成jar包怎么处理?只需要替换HDFS路径上的旧jar包,然后重启Hive客户端即可。

    三十.DWD_动作日志解析完成 

    5)数据导入

    hive (gmall)>

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_action_log partition(dt='2020-06-14')
    3. select
    4. get_json_object(line,'$.common.ar'),
    5. get_json_object(line,'$.common.ba'),
    6. get_json_object(line,'$.common.ch'),
    7. get_json_object(line,'$.common.md'),
    8. get_json_object(line,'$.common.mid'),
    9. get_json_object(line,'$.common.os'),
    10. get_json_object(line,'$.common.uid'),
    11. get_json_object(line,'$.common.vc'),
    12. get_json_object(line,'$.page.during_time'),
    13. get_json_object(line,'$.page.item'),
    14. get_json_object(line,'$.page.item_type'),
    15. get_json_object(line,'$.page.last_page_id'),
    16. get_json_object(line,'$.page.page_id'),
    17. get_json_object(line,'$.page.sourceType'),
    18. get_json_object(action,'$.action_id'),
    19. get_json_object(action,'$.item'),
    20. get_json_object(action,'$.item_type'),
    21. get_json_object(action,'$.ts')
    22. from ods_log lateral view explode_json_array(get_json_object(line,'$.actions')) tmp as action
    23. where dt='2020-06-14'
    24. and get_json_object(line,'$.actions') is not null;

    3)查看数据

    hive (gmall)>

    select * from dwd_action_log where dt='2020-06-14' limit 2;

     三十一.DWD_曝光日志

    曝光日志解析思路:曝光日志表中每行数据对应一个曝光记录,一个曝光记录应当包含公共信息、页面信息以及曝光信息。先将包含display字段的日志过滤出来,然后通过UDTF函数,将display数组“炸开”(类似于explode函数的效果),然后使用get_json_object函数解析每个字段。

    1)建表语句 

    1. hive (gmall)>
    2. drop table if exists dwd_display_log;
    3. CREATE EXTERNAL TABLE dwd_display_log(
    4. `area_code` string COMMENT '地区编码',
    5. `brand` string COMMENT '手机品牌',
    6. `channel` string COMMENT '渠道',
    7. `model` string COMMENT '手机型号',
    8. `mid_id` string COMMENT '设备id',
    9. `os` string COMMENT '操作系统',
    10. `user_id` string COMMENT '会员id',
    11. `version_code` string COMMENT 'app版本号',
    12. `during_time` bigint COMMENT 'app版本号',
    13. `page_item` string COMMENT '目标id ',
    14. `page_item_type` string COMMENT '目标类型',
    15. `last_page_id` string COMMENT '上页类型',
    16. `page_id` string COMMENT '页面ID ',
    17. `source_type` string COMMENT '来源类型',
    18. `ts` bigint COMMENT 'app版本号',
    19. `display_type` string COMMENT '曝光类型',
    20. `item` string COMMENT '曝光对象id ',
    21. `item_type` string COMMENT 'app版本号',
    22. `order` bigint COMMENT '出现顺序'
    23. ) COMMENT '曝光日志表'
    24. PARTITIONED BY (dt string)
    25. stored as parquet
    26. LOCATION '/warehouse/gmall/dwd/dwd_display_log'
    27. TBLPROPERTIES('parquet.compression'='lzo');

    2)数据导入
     

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_display_log partition(dt='2020-06-14')
    3. select
    4. get_json_object(line,'$.common.ar'),
    5. get_json_object(line,'$.common.ba'),
    6. get_json_object(line,'$.common.ch'),
    7. get_json_object(line,'$.common.md'),
    8. get_json_object(line,'$.common.mid'),
    9. get_json_object(line,'$.common.os'),
    10. get_json_object(line,'$.common.uid'),
    11. get_json_object(line,'$.common.vc'),
    12. get_json_object(line,'$.page.during_time'),
    13. get_json_object(line,'$.page.item'),
    14. get_json_object(line,'$.page.item_type'),
    15. get_json_object(line,'$.page.last_page_id'),
    16. get_json_object(line,'$.page.page_id'),
    17. get_json_object(line,'$.page.sourceType'),
    18. get_json_object(line,'$.ts'),
    19. get_json_object(display,'$.displayType'),
    20. get_json_object(display,'$.item'),
    21. get_json_object(display,'$.item_type'),
    22. get_json_object(display,'$.order')
    23. from ods_log lateral view explode_json_array(get_json_object(line,'$.displays')) tmp as display
    24. where dt='2020-06-14'
    25. and get_json_object(line,'$.displays') is not null;

    3)查看数据

    hive (gmall)>  select * from dwd_display_log where dt='2020-06-14' limit 2;

     三十二.页面信息解释

    比如说:我们进入一个页面点击了支付,在另一个页面也点击了支付,如何查看在哪个页面进行了点击

    三十三.错误日志表分析

    错误日志解析思路:错误日志表中每行数据对应一个错误记录,为方便定位错误,一个错误记录应当包含与之对应的公共信息、页面信息、曝光信息、动作信息、启动信息以及错误信息。先将包含err字段的日志过滤出来,然后使用get_json_object函数解析所有字段。 

    1)建表语句
     

    1. hive (gmall)>
    2. drop table if exists dwd_error_log;
    3. CREATE EXTERNAL TABLE dwd_error_log(
    4. `area_code` string COMMENT '地区编码',
    5. `brand` string COMMENT '手机品牌',
    6. `channel` string COMMENT '渠道',
    7. `model` string COMMENT '手机型号',
    8. `mid_id` string COMMENT '设备id',
    9. `os` string COMMENT '操作系统',
    10. `user_id` string COMMENT '会员id',
    11. `version_code` string COMMENT 'app版本号',
    12. `page_item` string COMMENT '目标id ',
    13. `page_item_type` string COMMENT '目标类型',
    14. `last_page_id` string COMMENT '上页类型',
    15. `page_id` string COMMENT '页面ID ',
    16. `source_type` string COMMENT '来源类型',
    17. `entry` string COMMENT ' icon手机图标 notice 通知 install 安装后启动',
    18. `loading_time` string COMMENT '启动加载时间',
    19. `open_ad_id` string COMMENT '广告页ID ',
    20. `open_ad_ms` string COMMENT '广告总共播放时间',
    21. `open_ad_skip_ms` string COMMENT '用户跳过广告时点',
    22. `actions` string COMMENT '动作',
    23. `displays` string COMMENT '曝光',
    24. `ts` string COMMENT '时间',
    25. `error_code` string COMMENT '错误码',
    26. `msg` string COMMENT '错误信息'
    27. ) COMMENT '错误日志表'
    28. PARTITIONED BY (dt string)
    29. stored as parquet
    30. LOCATION '/warehouse/gmall/dwd/dwd_error_log'
    31. TBLPROPERTIES('parquet.compression'='lzo');

    说明:此处为对动作数组和曝光数组做处理,如需分析错误与单个动作或曝光的关联,可先使用explode_json_array函数将数组“炸开”,再使用get_json_object函数获取具体字段。

    2)数据导入

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_error_log partition(dt='2020-06-14')
    3. select
    4. get_json_object(line,'$.common.ar'),
    5. get_json_object(line,'$.common.ba'),
    6. get_json_object(line,'$.common.ch'),
    7. get_json_object(line,'$.common.md'),
    8. get_json_object(line,'$.common.mid'),
    9. get_json_object(line,'$.common.os'),
    10. get_json_object(line,'$.common.uid'),
    11. get_json_object(line,'$.common.vc'),
    12. get_json_object(line,'$.page.item'),
    13. get_json_object(line,'$.page.item_type'),
    14. get_json_object(line,'$.page.last_page_id'),
    15. get_json_object(line,'$.page.page_id'),
    16. get_json_object(line,'$.page.sourceType'),
    17. get_json_object(line,'$.start.entry'),
    18. get_json_object(line,'$.start.loading_time'),
    19. get_json_object(line,'$.start.open_ad_id'),
    20. get_json_object(line,'$.start.open_ad_ms'),
    21. get_json_object(line,'$.start.open_ad_skip_ms'),
    22. get_json_object(line,'$.actions'),
    23. get_json_object(line,'$.displays'),
    24. get_json_object(line,'$.ts'),
    25. get_json_object(line,'$.err.error_code'),
    26. get_json_object(line,'$.err.msg')
    27. from ods_log
    28. where dt='2020-06-14'
    29. and get_json_object(line,'$.err') is not null;

    3)查看数据

    hive (gmall)>
    select * from dwd_error_log where dt='2020-06-14' limit 2;

    DWD层用户行为数据加载脚本

    1)在hadoop102的/home/atguigu/bin目录下创建脚本
    [atguigu@hadoop102 bin]$ vim ods_to_dwd_log.sh

    1. #!/bin/bash
    2. hive=/opt/module/hive/bin/hive
    3. APP=gmall
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$1" ] ;then
    6. do_date=$1
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql="
    11. SET mapreduce.job.queuename=hive;
    12. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    13. insert overwrite table ${APP}.dwd_start_log partition(dt='$do_date')
    14. select
    15. get_json_object(line,'$.common.ar'),
    16. get_json_object(line,'$.common.ba'),
    17. get_json_object(line,'$.common.ch'),
    18. get_json_object(line,'$.common.md'),
    19. get_json_object(line,'$.common.mid'),
    20. get_json_object(line,'$.common.os'),
    21. get_json_object(line,'$.common.uid'),
    22. get_json_object(line,'$.common.vc'),
    23. get_json_object(line,'$.start.entry'),
    24. get_json_object(line,'$.start.loading_time'),
    25. get_json_object(line,'$.start.open_ad_id'),
    26. get_json_object(line,'$.start.open_ad_ms'),
    27. get_json_object(line,'$.start.open_ad_skip_ms'),
    28. get_json_object(line,'$.ts')
    29. from ${APP}.ods_log
    30. where dt='$do_date'
    31. and get_json_object(line,'$.start') is not null;
    32. insert overwrite table ${APP}.dwd_action_log partition(dt='$do_date')
    33. select
    34. get_json_object(line,'$.common.ar'),
    35. get_json_object(line,'$.common.ba'),
    36. get_json_object(line,'$.common.ch'),
    37. get_json_object(line,'$.common.md'),
    38. get_json_object(line,'$.common.mid'),
    39. get_json_object(line,'$.common.os'),
    40. get_json_object(line,'$.common.uid'),
    41. get_json_object(line,'$.common.vc'),
    42. get_json_object(line,'$.page.during_time'),
    43. get_json_object(line,'$.page.item'),
    44. get_json_object(line,'$.page.item_type'),
    45. get_json_object(line,'$.page.last_page_id'),
    46. get_json_object(line,'$.page.page_id'),
    47. get_json_object(line,'$.page.sourceType'),
    48. get_json_object(action,'$.action_id'),
    49. get_json_object(action,'$.item'),
    50. get_json_object(action,'$.item_type'),
    51. get_json_object(action,'$.ts')
    52. from ${APP}.ods_log lateral view ${APP}.explode_json_array(get_json_object(line,'$.actions')) tmp as action
    53. where dt='$do_date'
    54. and get_json_object(line,'$.actions') is not null;
    55. insert overwrite table ${APP}.dwd_display_log partition(dt='$do_date')
    56. select
    57. get_json_object(line,'$.common.ar'),
    58. get_json_object(line,'$.common.ba'),
    59. get_json_object(line,'$.common.ch'),
    60. get_json_object(line,'$.common.md'),
    61. get_json_object(line,'$.common.mid'),
    62. get_json_object(line,'$.common.os'),
    63. get_json_object(line,'$.common.uid'),
    64. get_json_object(line,'$.common.vc'),
    65. get_json_object(line,'$.page.during_time'),
    66. get_json_object(line,'$.page.item'),
    67. get_json_object(line,'$.page.item_type'),
    68. get_json_object(line,'$.page.last_page_id'),
    69. get_json_object(line,'$.page.page_id'),
    70. get_json_object(line,'$.page.sourceType'),
    71. get_json_object(line,'$.ts'),
    72. get_json_object(display,'$.displayType'),
    73. get_json_object(display,'$.item'),
    74. get_json_object(display,'$.item_type'),
    75. get_json_object(display,'$.order')
    76. from ${APP}.ods_log lateral view ${APP}.explode_json_array(get_json_object(line,'$.displays')) tmp as display
    77. where dt='$do_date'
    78. and get_json_object(line,'$.displays') is not null;
    79. insert overwrite table ${APP}.dwd_page_log partition(dt='$do_date')
    80. select
    81. get_json_object(line,'$.common.ar'),
    82. get_json_object(line,'$.common.ba'),
    83. get_json_object(line,'$.common.ch'),
    84. get_json_object(line,'$.common.md'),
    85. get_json_object(line,'$.common.mid'),
    86. get_json_object(line,'$.common.os'),
    87. get_json_object(line,'$.common.uid'),
    88. get_json_object(line,'$.common.vc'),
    89. get_json_object(line,'$.page.during_time'),
    90. get_json_object(line,'$.page.item'),
    91. get_json_object(line,'$.page.item_type'),
    92. get_json_object(line,'$.page.last_page_id'),
    93. get_json_object(line,'$.page.page_id'),
    94. get_json_object(line,'$.page.sourceType'),
    95. get_json_object(line,'$.ts')
    96. from ${APP}.ods_log
    97. where dt='$do_date'
    98. and get_json_object(line,'$.page') is not null;
    99. insert overwrite table ${APP}.dwd_error_log partition(dt='$do_date')
    100. select
    101. get_json_object(line,'$.common.ar'),
    102. get_json_object(line,'$.common.ba'),
    103. get_json_object(line,'$.common.ch'),
    104. get_json_object(line,'$.common.md'),
    105. get_json_object(line,'$.common.mid'),
    106. get_json_object(line,'$.common.os'),
    107. get_json_object(line,'$.common.uid'),
    108. get_json_object(line,'$.common.vc'),
    109. get_json_object(line,'$.page.item'),
    110. get_json_object(line,'$.page.item_type'),
    111. get_json_object(line,'$.page.last_page_id'),
    112. get_json_object(line,'$.page.page_id'),
    113. get_json_object(line,'$.page.sourceType'),
    114. get_json_object(line,'$.start.entry'),
    115. get_json_object(line,'$.start.loading_time'),
    116. get_json_object(line,'$.start.open_ad_id'),
    117. get_json_object(line,'$.start.open_ad_ms'),
    118. get_json_object(line,'$.start.open_ad_skip_ms'),
    119. get_json_object(line,'$.actions'),
    120. get_json_object(line,'$.displays'),
    121. get_json_object(line,'$.ts'),
    122. get_json_object(line,'$.err.error_code'),
    123. get_json_object(line,'$.err.msg')
    124. from ${APP}.ods_log
    125. where dt='$do_date'
    126. and get_json_object(line,'$.err') is not null;
    127. "
    128. $hive -e "$sql"

    2)增加脚本执行权限
    [atguigu@hadoop102 bin]$ chmod 777 ods_to_dwd_log.sh

    3)脚本使用
    [atguigu@hadoop102 module]$ ods_to_dwd_log.sh 2020-06-15

    4)查询导入结果

    hive (gmall)>

    select * from dwd_start_log where dt='2020-06-15' limit 2;

    5)脚本执行时间

    企业开发中一般在每日凌晨30分~1点

    三十四.DWD_商品维度解析

    业务数据方面DWD层的搭建主要注意点在于维度的退化,减少后续大量Join操作。

    商品维度表 

    商品维度表主要是将商品表SKU表、商品一级分类、商品二级分类、商品三级分类、商品品牌表和商品SPU表退化为商品表。

    1)建表语句

    1. DROP TABLE IF EXISTS `dwd_dim_sku_info`;
    2. CREATE EXTERNAL TABLE `dwd_dim_sku_info` (
    3. `id` string COMMENT '商品id',
    4. `spu_id` string COMMENT 'spuid',
    5. `price` decimal(16,2) COMMENT '商品价格',
    6. `sku_name` string COMMENT '商品名称',
    7. `sku_desc` string COMMENT '商品描述',
    8. `weight` decimal(16,2) COMMENT '重量',
    9. `tm_id` string COMMENT '品牌id',
    10. `tm_name` string COMMENT '品牌名称',
    11. `category3_id` string COMMENT '三级分类id',
    12. `category2_id` string COMMENT '二级分类id',
    13. `category1_id` string COMMENT '一级分类id',
    14. `category3_name` string COMMENT '三级分类名称',
    15. `category2_name` string COMMENT '二级分类名称',
    16. `category1_name` string COMMENT '一级分类名称',
    17. `spu_name` string COMMENT 'spu名称',
    18. `create_time` string COMMENT '创建时间'
    19. ) COMMENT '商品维度表'
    20. PARTITIONED BY (`dt` string)
    21. stored as parquet
    22. location '/warehouse/gmall/dwd/dwd_dim_sku_info/'
    23. tblproperties ("parquet.compression"="lzo");

     2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_sku_info partition(dt='2020-06-14')
    3. select
    4. sku.id, --- 通过下面起别名的方式取出id
    5. sku.spu_id, --- 通过下面起别名的方式取出spu_id
    6. sku.price,
    7. sku.sku_name,
    8. sku.sku_desc, --- 描述
    9. sku.weight, --- 重量
    10. sku.tm_id, --- 品牌id
    11. ob.tm_name, --- 品牌名称
    12. sku.category3_id,
    13. c2.id category2_id,
    14. c1.id category1_id,
    15. c3.name category3_name,
    16. c2.name category2_name,
    17. c1.name category1_name,
    18. spu.spu_name,
    19. sku.create_time
    20. from
    21. (
    22. select * from ods_sku_info where dt='2020-06-14'
    23. )sku --- 以sku为主,sku是个别名
    24. join
    25. (
    26. select * from ods_base_trademark where dt='2020-06-14'
    27. )ob on sku.tm_id=ob.tm_id 后面就是一个进行join的过程,需要谁就是与谁进行join,ob是一个别名
    28. join
    29. (
    30. select * from ods_spu_info where dt='2020-06-14'
    31. )spu on spu.id = sku.spu_id 需要谁和谁进行join
    32. join
    33. (
    34. select * from ods_base_category3 where dt='2020-06-14'
    35. )c3 on sku.category3_id=c3.id
    36. join
    37. (
    38. select * from ods_base_category2 where dt='2020-06-14'
    39. )c2 on c3.category2_id=c2.id
    40. join
    41. (
    42. select * from ods_base_category1 where dt='2020-06-14'
    43. )c1 on c2.category1_id=c1.id;

    3)查询加载结果
    hive (gmall)> select * from dwd_dim_sku_info where dt='2020-06-14' limit 2;

    三十五.DWD_优惠券维度表

    把ODS层ods_coupon_info表数据导入到DWD层优惠卷维度表,在导入过程中可以做适当的清洗。

    1)建表语句

    1. drop table if exists dwd_dim_coupon_info;
    2. create external table dwd_dim_coupon_info(
    3. `id` string COMMENT '购物券编号',
    4. `coupon_name` string COMMENT '购物券名称',
    5. `coupon_type` string COMMENT '购物券类型 1 现金券 2 折扣券 3 满减券 4 满件打折券',
    6. `condition_amount` decimal(16,2) COMMENT '满额数',
    7. `condition_num` bigint COMMENT '满件数',
    8. `activity_id` string COMMENT '活动编号',
    9. `benefit_amount` decimal(16,2) COMMENT '减金额',
    10. `benefit_discount` decimal(16,2) COMMENT '折扣',
    11. `create_time` string COMMENT '创建时间',
    12. `range_type` string COMMENT '范围类型 1、商品 2、品类 3、品牌',
    13. `spu_id` string COMMENT '商品id',
    14. `tm_id` string COMMENT '品牌id',
    15. `category3_id` string COMMENT '品类id',
    16. `limit_num` bigint COMMENT '最多领用次数',
    17. `operate_time` string COMMENT '修改时间',
    18. `expire_time` string COMMENT '过期时间'
    19. ) COMMENT '优惠券维度表'
    20. PARTITIONED BY (`dt` string)
    21. stored as parquet
    22. location '/warehouse/gmall/dwd/dwd_dim_coupon_info/'
    23. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_coupon_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. coupon_name,
    6. coupon_type,
    7. condition_amount,
    8. condition_num,
    9. activity_id,
    10. benefit_amount,
    11. benefit_discount,
    12. create_time,
    13. range_type,
    14. spu_id,
    15. tm_id,
    16. category3_id,
    17. limit_num,
    18. operate_time,
    19. expire_time
    20. from ods_coupon_info
    21. where dt='2020-06-14';

    3)查询加载结果
    hive (gmall)> select * from dwd_dim_coupon_info where dt='2020-06-14' limit 2;

    三十六.活动维度表(全量)

    活动维度表

    1)建表语句

    1. drop table if exists dwd_dim_activity_info;
    2. create external table dwd_dim_activity_info(
    3. `id` string COMMENT '编号',
    4. `activity_name` string COMMENT '活动名称',
    5. `activity_type` string COMMENT '活动类型',
    6. `start_time` string COMMENT '开始时间',
    7. `end_time` string COMMENT '结束时间',
    8. `create_time` string COMMENT '创建时间'
    9. ) COMMENT '活动信息表'
    10. PARTITIONED BY (`dt` string)
    11. stored as parquet
    12. location '/warehouse/gmall/dwd/dwd_dim_activity_info/'
    13. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_activity_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. activity_name,
    6. activity_type,
    7. start_time,
    8. end_time,
    9. create_time
    10. from ods_activity_info
    11. where dt='2020-06-14';

     3)查询结果

    select * from dwd_dim_activity_info where dt='2020-06-14' limit 2

    自定义UDTF函数的一个好处,为什么不使用系统的炸裂函数?
    理由:自定义UDTF函数的好处是可以快速定义到函数的问题.更加的灵活,可以快速定义到问题.

    脚本之中进行执行的时候,自定义函数前面也是需要增加库名的,第一遍自己写没有添加会导致执行不下去.

    自定义函数声明问题:自定义函数是以库为单位,并不是全局的,不能够跨越库去执行相应的函数.

    自定义UDTF函数的步骤:
    (1)定义一个类,继承G..UDTF
    (2)重写里面的三个方法,初始化(输入参数的个数 和类型校验 定义返回值名称 校验返回值类型)
    process(支持多进多出,本次项目是用的是=>1进多出 object[0].toString forward)
    close
    (3)打包+上传(hdfs集群路径)
    (4)在hive客户端进行注册gmall->create function ex_json_array as "全类名" using "hdfs://hadoop"

    stored as parquet + lzo 是支持切片的

    三十七.DWD_业务_维度退化

    进行相应的join操作,进而得到相应的维度退化过程.(面试:对于哪些表进行了维度退化
    省份表和地区表-------地区表
    商品表 spu 品类表 三级分类 二级分类 一级分类------商品维度表
    时间 (年 月 日)-------时间维度表

    三十八.DWD_业务_ETL清洗

    ETL内容:(1)数据清洗,就是进行相应的数据解析; (2)核心字段不能为空.(3)超时信息进行过滤.(4)重复数据进行过滤.(5)核心字段错误,进行过滤.

    清洗手段:hql,spark sql,python,MR,Kettle(深圳比较多,北京是比较少的)

    来了10000条日志,这里需要进行清洗的数据是多少. 10000条数据算正常,但是一旦超过了10000条,找谁

    用户行为数据(点赞) 业务数据(点赞) 当他们都是存在的时候,
    1.正常情况下我们是使用业务数据的.(优先选择业务)
    2.拼接:业务 | 用户行为
    有业务用业务,但是当业务Hi空的时候用用户行为的.

    三十九.DWD_业务_活动维度

    1)建表语句

    1. drop table if exists dwd_dim_activity_info;
    2. create external table dwd_dim_activity_info(
    3. `id` string COMMENT '编号',
    4. `activity_name` string COMMENT '活动名称',
    5. `activity_type` string COMMENT '活动类型',
    6. `start_time` string COMMENT '开始时间',
    7. `end_time` string COMMENT '结束时间',
    8. `create_time` string COMMENT '创建时间'
    9. ) COMMENT '活动信息表'
    10. PARTITIONED BY (`dt` string)
    11. stored as parquet
    12. location '/warehouse/gmall/dwd/dwd_dim_activity_info/'
    13. tblproperties ("parquet.compression"="lzo");

     2) 数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_activity_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. activity_name,
    6. activity_type,
    7. start_time,
    8. end_time,
    9. create_time
    10. from ods_activity_info
    11. where dt='2020-06-14';

    3)查询加载结果

    hive (gmall)> select * from dwd_dim_activity_info where dt='2020-06-14' limit 2;

    四十.DWD_业务_地区维度

    1)创建表

    1. DROP TABLE IF EXISTS `dwd_dim_base_province`;
    2. CREATE EXTERNAL TABLE `dwd_dim_base_province` (
    3. `id` string COMMENT 'id',
    4. `province_name` string COMMENT '省市名称',
    5. `area_code` string COMMENT '地区编码',
    6. `iso_code` string COMMENT 'ISO编码',
    7. `region_id` string COMMENT '地区id',
    8. `region_name` string COMMENT '地区名称'
    9. ) COMMENT '地区维度表'
    10. stored as parquet
    11. location '/warehouse/gmall/dwd/dwd_dim_base_province/'
    12. tblproperties ("parquet.compression"="lzo");

     2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_base_province
    3. select
    4. bp.id,
    5. bp.name,
    6. bp.area_code,
    7. bp.iso_code,
    8. bp.region_id,
    9. br.region_name
    10. from
    11. (
    12. select * from ods_base_province
    13. ) bp
    14. join
    15. (
    16. select * from ods_base_region
    17. ) br
    18. on bp.region_id = br.id;

    3)查询加载结果
     select * from dwd_dim_base_province limit 2;

    四十一.DWD_业务_时间维度

    1)建表语句

    1. DROP TABLE IF EXISTS `dwd_dim_date_info`;
    2. CREATE EXTERNAL TABLE `dwd_dim_date_info`(
    3. `date_id` string ,
    4. `week_id` string ,
    5. `week_day` string ,
    6. `day` string ,
    7. `month` string ,
    8. `quarter` string ,
    9. `year` string ,
    10. `is_workday` string ,
    11. `holiday_id` string
    12. )
    13. stored as parquet
    14. location '/warehouse/gmall/dwd/dwd_dim_date_info/'
    15. tblproperties ("parquet.compression"="lzo");

    2)把date_info.txt文件上传到hadoop102的/opt/module/db_log/路径

    3)数据装载

    注意:由于dwd_dim_date_info是列式存储+LZO压缩。直接将date_info.txt文件导入到目标表,并不会直接转换为列式存储+LZO压缩。我们需要创建一张普通的临时表dwd_dim_date_info_tmp,将date_info.txt加载到该临时表中。最后通过查询临时表数据,把查询到的数据插入到最终的目标表中。

    (1)创建临时表,非列式存储

    1. DROP TABLE IF EXISTS `dwd_dim_date_info_tmp`;
    2. CREATE EXTERNAL TABLE `dwd_dim_date_info_tmp`(
    3. `date_id` string ,
    4. `week_id` string ,
    5. `week_day` string ,
    6. `day` string ,
    7. `month` string ,
    8. `quarter` string ,
    9. `year` string ,
    10. `is_workday` string ,
    11. `holiday_id` string
    12. )
    13. row format delimited fields terminated by '\t'
    14. location '/warehouse/gmall/dwd/dwd_dim_date_info_tmp/';

    (2)将数据导入临时表

    load data local inpath '/opt/module/db_log/date_info.txt' into table dwd_dim_date_info_tmp;

    (3)将数据导入正式表

    insert overwrite table dwd_dim_date_info select * from dwd_dim_date_info_tmp;

    4)查询加载结果

    hive (gmall)> select * from dwd_dim_date_info;

    上面的过程就是将date——info.txt之中的数据先是导入到临时表之中,然后在使用列式存储的方法和lzo压缩将上述的东西直接再存入表中。

    四十二.DWD_业务_支付事实表

     1)建表语句

    1. drop table if exists dwd_fact_payment_info;
    2. create external table dwd_fact_payment_info (
    3. `id` string COMMENT 'id',
    4. `out_trade_no` string COMMENT '对外业务编号',
    5. `order_id` string COMMENT '订单编号',
    6. `user_id` string COMMENT '用户编号',
    7. `alipay_trade_no` string COMMENT '支付宝交易流水编号',
    8. `payment_amount` decimal(16,2) COMMENT '支付金额',
    9. `subject` string COMMENT '交易内容',
    10. `payment_type` string COMMENT '支付类型',
    11. `payment_time` string COMMENT '支付时间',
    12. `province_id` string COMMENT '省份ID'
    13. ) COMMENT '支付事实表表'
    14. PARTITIONED BY (`dt` string)
    15. stored as parquet
    16. location '/warehouse/gmall/dwd/dwd_fact_payment_info/'
    17. tblproperties ("parquet.compression"="lzo");

     2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_payment_info partition(dt='2020-06-14')
    3. select
    4. pi.id,
    5. pi.out_trade_no,
    6. pi.order_id,
    7. pi.user_id,
    8. pi.alipay_trade_no,
    9. pi.total_amount,
    10. pi.subject,
    11. pi.payment_type,
    12. pi.payment_time,
    13. oi.province_id
    14. from
    15. (
    16. select * from ods_payment_info where dt='2020-06-14'
    17. )pi
    18. join
    19. (
    20. select id, province_id from ods_order_info where dt='2020-06-14'
    21. )oi
    22. on pi.order_id = oi.id;

    这里的join里面的select是可以进行随便写的(在实际的企业之中,*是不可以出现的,因为会影响性能),on是对应条件。

    3)查询结果

    hive (gmall)> select * from dwd_fact_payment_info where dt='2020-06-14' limit 2;

    四十三.DWD_业务_退款事实表

    把ODS层ods_order_refund_info表数据导入到DWD层退款事实表,在导入过程中可以做适当的清洗。

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    退款

    件数/金额

    1)建表语句

    1. drop table if exists dwd_fact_order_refund_info;
    2. create external table dwd_fact_order_refund_info(
    3. `id` string COMMENT '编号',
    4. `user_id` string COMMENT '用户ID',
    5. `order_id` string COMMENT '订单ID',
    6. `sku_id` string COMMENT '商品ID',
    7. `refund_type` string COMMENT '退款类型',
    8. `refund_num` bigint COMMENT '退款件数',
    9. `refund_amount` decimal(16,2) COMMENT '退款金额',
    10. `refund_reason_type` string COMMENT '退款原因类型',
    11. `create_time` string COMMENT '退款时间'
    12. ) COMMENT '退款事实表'
    13. PARTITIONED BY (`dt` string)
    14. stored as parquet
    15. location '/warehouse/gmall/dwd/dwd_fact_order_refund_info/'
    16. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_order_refund_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. user_id,
    6. order_id,
    7. sku_id,
    8. refund_type,
    9. refund_num,
    10. refund_amount,
    11. refund_reason_type,
    12. create_time
    13. from ods_order_refund_info
    14. where dt='2020-06-14';

    3)查询结果
    select * from dwd_fact_order_refund_info where dt='2020-06-14' limit 2;

    四十四.DWD_业务_评价事实表

    把ODS层ods_comment_info表数据导入到DWD层评价事实表,在导入过程中可以做适当的清洗。

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    评价

    个数

    1)建表语句

    1. drop table if exists dwd_fact_comment_info;
    2. create external table dwd_fact_comment_info(
    3. `id` string COMMENT '编号',
    4. `user_id` string COMMENT '用户ID',
    5. `sku_id` string COMMENT '商品sku',
    6. `spu_id` string COMMENT '商品spu',
    7. `order_id` string COMMENT '订单ID',
    8. `appraise` string COMMENT '评价',
    9. `create_time` string COMMENT '评价时间'
    10. ) COMMENT '评价事实表'
    11. PARTITIONED BY (`dt` string)
    12. stored as parquet
    13. location '/warehouse/gmall/dwd/dwd_fact_comment_info/'
    14. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_comment_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. user_id,
    6. sku_id,
    7. spu_id,
    8. order_id,
    9. appraise,
    10. create_time
    11. from ods_comment_info
    12. where dt='2020-06-14';

    3)查询加载结果

    select * from dwd_fact_comment_info where dt='2020-06-14' limit 2;

    四十五.DWD_业务_订单详情事实表-217

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    订单详情

    件数/金额

    阿里的一道面试题:如下所示,

    上面需要进行考虑的是一个分摊情况,在相应的字段之中的表示

     1)建表语句

    1. drop table if exists dwd_fact_order_detail;
    2. create external table dwd_fact_order_detail (
    3. `id` string COMMENT '订单编号',
    4. `order_id` string COMMENT '订单号',
    5. `user_id` string COMMENT '用户id',
    6. `sku_id` string COMMENT 'sku商品id',
    7. `sku_name` string COMMENT '商品名称',
    8. `order_price` decimal(16,2) COMMENT '商品价格',
    9. `sku_num` bigint COMMENT '商品数量',
    10. `create_time` string COMMENT '创建时间',
    11. `province_id` string COMMENT '省份ID',
    12. `source_type` string COMMENT '来源类型',
    13. `source_id` string COMMENT '来源编号',
    14. `original_amount_d` decimal(20,2) COMMENT '原始价格分摊',
    15. `final_amount_d` decimal(20,2) COMMENT '购买价格分摊',
    16. `feight_fee_d` decimal(20,2) COMMENT '分摊运费',
    17. `benefit_reduce_amount_d` decimal(20,2) COMMENT '分摊优惠'
    18. ) COMMENT '订单明细事实表表'
    19. PARTITIONED BY (`dt` string)
    20. stored as parquet
    21. location '/warehouse/gmall/dwd/dwd_fact_order_detail/'
    22. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_order_detail partition(dt='2020-06-14')
    3. select
    4. id,
    5. order_id,
    6. user_id,
    7. sku_id,
    8. sku_name,
    9. order_price,
    10. sku_num,
    11. create_time,
    12. province_id,
    13. source_type,
    14. source_id,
    15. original_amount_d,
    16. if(rn=1,final_total_amount -(sum_div_final_amount - final_amount_d),final_amount_d),
    17. if(rn=1,feight_fee - (sum_div_feight_fee - feight_fee_d),feight_fee_d),
    18. if(rn=1,benefit_reduce_amount - (sum_div_benefit_reduce_amount -benefit_reduce_amount_d), benefit_reduce_amount_d)
    19. from
    20. (
    21. select
    22. od.id,
    23. od.order_id,
    24. od.user_id,
    25. od.sku_id,
    26. od.sku_name,
    27. od.order_price,
    28. od.sku_num,
    29. od.create_time,
    30. oi.province_id,
    31. od.source_type,
    32. od.source_id,
    33. round(od.order_price*od.sku_num,2) original_amount_d,
    34. round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2) final_amount_d,
    35. round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2) feight_fee_d,
    36. round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2) benefit_reduce_amount_d,
    37. row_number() over(partition by od.order_id order by od.id desc) rn,
    38. oi.final_total_amount,
    39. oi.feight_fee,
    40. oi.benefit_reduce_amount,
    41. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2)) over(partition by od.order_id) sum_div_final_amount,
    42. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2)) over(partition by od.order_id) sum_div_feight_fee,
    43. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2)) over(partition by od.order_id) sum_div_benefit_reduce_amount
    44. from
    45. (
    46. select * from ods_order_detail where dt='2020-06-14'
    47. ) od
    48. join
    49. (
    50. select * from ods_order_info where dt='2020-06-14'
    51. ) oi
    52. on od.order_id=oi.id
    53. )t1;

    上面代码的核心是对于分摊的操作,如下所示:

    阿里面试题上来了, 

    3)查询加载结果

    hive (gmall)> select * from dwd_fact_order_detail where dt='2020-06-14' limit 2;

    四十六.DWD层_业务_订单加购表

    由于购物车的数量是会发生变化,所以导增量不合适。

    每天做一次快照,导入的数据是全量,区别于事务型事实表是每天导入新增

    周期型快照事实表劣势:存储的数据量会比较大。

    解决方案:周期型快照事实表存储的数据比较讲究时效性,时间太久了的意义不大,可以删除以前的数据。

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    加购

    件数/金额

    1)建表语句

    1. drop table if exists dwd_fact_cart_info;
    2. create external table dwd_fact_cart_info(
    3. `id` string COMMENT '编号',
    4. `user_id` string COMMENT '用户id',
    5. `sku_id` string COMMENT 'skuid',
    6. `cart_price` string COMMENT '放入购物车时价格',
    7. `sku_num` string COMMENT '数量',
    8. `sku_name` string COMMENT 'sku名称 (冗余)',
    9. `create_time` string COMMENT '创建时间',
    10. `operate_time` string COMMENT '修改时间',
    11. `is_ordered` string COMMENT '是否已经下单。1为已下单;0为未下单',
    12. `order_time` string COMMENT '下单时间',
    13. `source_type` string COMMENT '来源类型',
    14. `srouce_id` string COMMENT '来源编号'
    15. ) COMMENT '加购事实表'
    16. PARTITIONED BY (`dt` string)
    17. stored as parquet
    18. location '/warehouse/gmall/dwd/dwd_fact_cart_info/'
    19. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_cart_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. user_id,
    6. sku_id,
    7. cart_price,
    8. sku_num,
    9. sku_name,
    10. create_time,
    11. operate_time,
    12. is_ordered,
    13. order_time,
    14. source_type,
    15. source_id
    16. from ods_cart_info
    17. where dt='2020-06-14';

    3)查询结果
     select * from dwd_fact_cart_info where dt='2020-06-14' limit 2;

    四十七.DWD层_业务_收藏事实表

    收藏的标记,是否取消,会发生变化,做增量不合适。

    每天做一次快照,导入的数据是全量,区别于事务型事实表是每天导入新增

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    收藏

    个数

    1)建表语句

    1. drop table if exists dwd_fact_favor_info;
    2. create external table dwd_fact_favor_info(
    3. `id` string COMMENT '编号',
    4. `user_id` string COMMENT '用户id',
    5. `sku_id` string COMMENT 'skuid',
    6. `spu_id` string COMMENT 'spuid',
    7. `is_cancel` string COMMENT '是否取消',
    8. `create_time` string COMMENT '收藏时间',
    9. `cancel_time` string COMMENT '取消时间'
    10. ) COMMENT '收藏事实表'
    11. PARTITIONED BY (`dt` string)
    12. stored as parquet
    13. location '/warehouse/gmall/dwd/dwd_fact_favor_info/'
    14. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_fact_favor_info partition(dt='2020-06-14')
    3. select
    4. id,
    5. user_id,
    6. sku_id,
    7. spu_id,
    8. is_cancel,
    9. create_time,
    10. cancel_time
    11. from ods_favor_info
    12. where dt='2020-06-14';

    3)查询结果查询

    select * from dwd_fact_favor_info where dt='2020-06-14' limit 2;

    四十八.DWD层_业务_优惠券领用事实表

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    优惠券领用

    个数

    优惠卷的生命周期:领取优惠卷-》用优惠卷下单-》优惠卷参与支付

    累积型快照事实表使用:统计优惠卷领取次数、优惠卷下单次数、优惠卷参与支付次数

    1)建表语句

    1. drop table if exists dwd_fact_coupon_use;
    2. create external table dwd_fact_coupon_use(
    3. `id` string COMMENT '编号',
    4. `coupon_id` string COMMENT '优惠券ID',
    5. `user_id` string COMMENT 'userid',
    6. `order_id` string COMMENT '订单id',
    7. `coupon_status` string COMMENT '优惠券状态',
    8. `get_time` string COMMENT '领取时间',
    9. `using_time` string COMMENT '使用时间(下单)',
    10. `used_time` string COMMENT '使用时间(支付)'
    11. ) COMMENT '优惠券领用事实表'
    12. PARTITIONED BY (`dt` string)
    13. stored as parquet
    14. location '/warehouse/gmall/dwd/dwd_fact_coupon_use/'
    15. tblproperties ("parquet.compression"="lzo");

    注意:dt是按照优惠卷领用时间get_time做为分区。

    2)数据装载

    注意下面的代码之中有一句动态分区非严格模式,如果要是没有这一句的话会进行相应的报错.在非严格模式下,分区是开始不用指定的.

    1. set hive.exec.dynamic.partition.mode=nonstrict;
    2. set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    3. insert overwrite table dwd_fact_coupon_use partition(dt)
    4. select
    5. if(new.id is null,old.id,new.id),
    6. if(new.coupon_id is null,old.coupon_id,new.coupon_id),
    7. if(new.user_id is null,old.user_id,new.user_id),
    8. if(new.order_id is null,old.order_id,new.order_id),
    9. if(new.coupon_status is null,old.coupon_status,new.coupon_status),
    10. if(new.get_time is null,old.get_time,new.get_time),
    11. if(new.using_time is null,old.using_time,new.using_time),
    12. if(new.used_time is null,old.used_time,new.used_time),
    13. date_format(if(new.get_time is null,old.get_time,new.get_time),'yyyy-MM-dd')
    14. from
    15. (
    16. select
    17. id,
    18. coupon_id,
    19. user_id,
    20. order_id,
    21. coupon_status,
    22. get_time,
    23. using_time,
    24. used_time
    25. from dwd_fact_coupon_use
    26. where dt in
    27. (
    28. select
    29. date_format(get_time,'yyyy-MM-dd')
    30. from ods_coupon_use
    31. where dt='2020-06-14'
    32. )
    33. )old
    34. full outer join
    35. (
    36. select
    37. id,
    38. coupon_id,
    39. user_id,
    40. order_id,
    41. coupon_status,
    42. get_time,
    43. using_time,
    44. used_time
    45. from ods_coupon_use
    46. where dt='2020-06-14'
    47. )new
    48. on old.id=new.id;

    上面是使用的全连接的过程,就是有不同的地方进行补充.先是选出来未来要被覆盖的数据,全外连接相应的新产生的数据.

    3)查询加载结果

    hive (gmall)> select * from dwd_fact_coupon_use where dt='2020-06-14' limit 2;

    四十九.DWD_业务_系统函数(concatconcat_wscollect_setSTR_TO_MAP

    1)concat函数

    concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL

    2)concat_ws函数

    concat_ws函数在连接字符串的时候,只要有一个字符串不是NULL,就不会返回NULL。concat_ws函数需要指定分隔符。

    3)STR_TO_MAP函数

    (1)语法描述

    STR_TO_MAP(VARCHAR text, VARCHAR listDelimiter, VARCHAR keyValueDelimiter)

    (2)功能描述

    使用listDelimiter将text分隔成K-V对,然后使用keyValueDelimiter分隔每个K-V对,组装成MAP返回。默认listDelimiter为( ,),keyValueDelimiter为(=)。

    (3)案例

    str_to_map('1001=2020-06-14,1002=2020-06-14',  ','  ,  '=')

    输出

    {"1001":"2020-06-14","1002":"2020-06-14"}
    这个地方的含义就是使用了两刀进行了切割的过程.

    五十.DWD_业务_订单表分析

    时间

    用户

    地区

    商品

    优惠券

    活动

    编码

    度量值

    订单

    件数/金额

    订单生命周期:创建时间=》支付时间=》取消时间=》完成时间=》退款时间=》退款完成时间。

    由于ODS层订单表只有创建时间和操作时间两个状态,不能表达所有时间含义,所以需要关联订单状态表。订单事实表里面增加了活动id,所以需要关联活动订单表。

    1)建表语句

    1. drop table if exists dwd_fact_order_info;
    2. create external table dwd_fact_order_info (
    3. `id` string COMMENT '订单编号',
    4. `order_status` string COMMENT '订单状态',
    5. `user_id` string COMMENT '用户id',
    6. `out_trade_no` string COMMENT '支付流水号',
    7. `create_time` string COMMENT '创建时间(未支付状态)',
    8. `payment_time` string COMMENT '支付时间(已支付状态)',
    9. `cancel_time` string COMMENT '取消时间(已取消状态)',
    10. `finish_time` string COMMENT '完成时间(已完成状态)',
    11. `refund_time` string COMMENT '退款时间(退款中状态)',
    12. `refund_finish_time` string COMMENT '退款完成时间(退款完成状态)',
    13. `province_id` string COMMENT '省份ID',
    14. `activity_id` string COMMENT '活动ID',
    15. `original_total_amount` decimal(16,2) COMMENT '原价金额',
    16. `benefit_reduce_amount` decimal(16,2) COMMENT '优惠金额',
    17. `feight_fee` decimal(16,2) COMMENT '运费',
    18. `final_total_amount` decimal(16,2) COMMENT '订单金额'
    19. ) COMMENT '订单事实表'
    20. PARTITIONED BY (`dt` string)
    21. stored as parquet
    22. location '/warehouse/gmall/dwd/dwd_fact_order_info/'
    23. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    3)常用函数

    select order_id, concat(order_status,'=', operate_time) from ods_order_status_log where dt='2020-06-14';

    select order_id, collect_set(concat(order_status,'=',operate_time)) from ods_order_status_log where dt='2020-06-14' group by order_id; //这句话的含义就是将上面的订单id是相同的数据进行一个聚合,相同的聚合到一行上面,多行转为一行.按照订单的id.

    select order_id, concat_ws(',', collect_set(concat(order_status,'=',operate_time))) from ods_order_status_log where dt='2020-06-14' group by order_id;//将上面的数据使用,进行分割.

    可见原来是数组的样子,现在完全是一个字符串的样子. 

    select order_id, str_to_map(concat_ws(',',collect_set(concat(order_status,'=',operate_time))), ','  ,  '=') from ods_order_status_log where dt='2020-06-14' group by order_id;//我们将其变成一个map的样子,里面的状态值对应着不同的含义.

    4) 数据装载代码

    1. set hive.exec.dynamic.partition.mode=nonstrict;
    2. set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    3. insert overwrite table dwd_fact_order_info partition(dt)
    4. select
    5. if(new.id is null,old.id,new.id),
    6. if(new.order_status is null,old.order_status,new.order_status),
    7. if(new.user_id is null,old.user_id,new.user_id),
    8. if(new.out_trade_no is null,old.out_trade_no,new.out_trade_no),
    9. if(new.tms['1001'] is null,old.create_time,new.tms['1001']),--1001对应未支付状态
    10. if(new.tms['1002'] is null,old.payment_time,new.tms['1002']),
    11. if(new.tms['1003'] is null,old.cancel_time,new.tms['1003']),
    12. if(new.tms['1004'] is null,old.finish_time,new.tms['1004']),
    13. if(new.tms['1005'] is null,old.refund_time,new.tms['1005']),
    14. if(new.tms['1006'] is null,old.refund_finish_time,new.tms['1006']),
    15. if(new.province_id is null,old.province_id,new.province_id),
    16. if(new.activity_id is null,old.activity_id,new.activity_id),
    17. if(new.original_total_amount is null,old.original_total_amount,new.original_total_amount),
    18. if(new.benefit_reduce_amount is null,old.benefit_reduce_amount,new.benefit_reduce_amount),
    19. if(new.feight_fee is null,old.feight_fee,new.feight_fee),
    20. if(new.final_total_amount is null,old.final_total_amount,new.final_total_amount),
    21. date_format(if(new.tms['1001'] is null,old.create_time,new.tms['1001']),'yyyy-MM-dd')
    22. from
    23. (
    24. select
    25. id,
    26. order_status,
    27. user_id,
    28. out_trade_no,
    29. create_time,
    30. payment_time,
    31. cancel_time,
    32. finish_time,
    33. refund_time,
    34. refund_finish_time,
    35. province_id,
    36. activity_id,
    37. original_total_amount,
    38. benefit_reduce_amount,
    39. feight_fee,
    40. final_total_amount
    41. from dwd_fact_order_info
    42. where dt
    43. in
    44. (
    45. select
    46. date_format(create_time,'yyyy-MM-dd')
    47. from ods_order_info
    48. where dt='2020-06-14'
    49. )
    50. )old
    51. full outer join
    52. (
    53. select
    54. info.id,
    55. info.order_status,
    56. info.user_id,
    57. info.out_trade_no,
    58. info.province_id,
    59. act.activity_id,
    60. log.tms,
    61. info.original_total_amount,
    62. info.benefit_reduce_amount,
    63. info.feight_fee,
    64. info.final_total_amount
    65. from
    66. (
    67. select
    68. order_id,
    69. str_to_map(concat_ws(',',collect_set(concat(order_status,'=',operate_time))),',','=') tms
    70. from ods_order_status_log
    71. where dt='2020-06-14'
    72. group by order_id
    73. )log
    74. join
    75. (
    76. select * from ods_order_info where dt='2020-06-14'
    77. )info
    78. on log.order_id=info.id
    79. left join
    80. (
    81. select * from ods_activity_order where dt='2020-06-14'
    82. )act
    83. on log.order_id=act.order_id
    84. )new
    85. on old.id=new.id;

    5)查询加载结果

    hive (gmall)> select * from dwd_fact_order_info where dt='2020-06-14' limit 2;

    五十一.DWD_业务_用户拉链表(非常重要的)

    面试会问:
    1.项目之中有没有用过拉链表?
    2.用户的某一特征是变化的,但是不是经常变化的,请问你应该如何处理?(比如说是手机号为例子)

    用户表中的数据每日既有可能新增,也有可能修改,但修改频率并不高,属于缓慢变化维度,此处采用拉链表存储用户维度数据。
    1)什么是拉链表

    拉链表,记录每条信息的生命周期,一旦一条记录的生命周期结束,就是会进行重新放入一个新的记录,并把当前日期作为生效开始日期.如果当前的信息任然是有效的,在生效结束日期前填入一个极大值(9999-99-99)

    2) 为什么要使用拉链表?

    拉链表适用于数据缓慢变化的数据,可以大大节约使用的空间.

    3) 如何使用拉链表?

     4) 拉链表的形成过程

     5)拉链表制作过程图

     用户当日全部数据和MySQL中每天变化的数据拼接到一起,形成一个新的临时的拉链数据表.用临时的拉链数据表去覆盖掉旧的拉链数据表.

    6)拉链表制作过程

    步骤0:初始化拉链表(首次独立执行)

    (1)建立拉链表

    1. drop table if exists dwd_dim_user_info_his;
    2. create external table dwd_dim_user_info_his(
    3. `id` string COMMENT '用户id',
    4. `name` string COMMENT '姓名',
    5. `birthday` string COMMENT '生日',
    6. `gender` string COMMENT '性别',
    7. `email` string COMMENT '邮箱',
    8. `user_level` string COMMENT '用户等级',
    9. `create_time` string COMMENT '创建时间',
    10. `operate_time` string COMMENT '操作时间',
    11. `start_date` string COMMENT '有效开始日期',
    12. `end_date` string COMMENT '有效结束日期'
    13. ) COMMENT '用户拉链表'
    14. stored as parquet
    15. location '/warehouse/gmall/dwd/dwd_dim_user_info_his/'
    16. tblproperties ("parquet.compression"="lzo");

    (2)初始化拉链表------在原来的用户表上加上两列

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_user_info_his
    3. select
    4. id,
    5. name,
    6. birthday,
    7. gender,
    8. email,
    9. user_level,
    10. create_time,
    11. operate_time,
    12. '2020-06-14',
    13. '9999-99-99'
    14. from ods_user_info oi
    15. where oi.dt='2020-06-14';

    步骤1:制作当日变动数据(包括新增,修改)每日执行

    (1)如何获得每日变动表

    a.最好表内有创建时间和变动时间(Lucky!

    b.如果没有,可以利用第三方工具监控比如canal(后面会说到),监控MySQL的实时变化进行记录(麻烦)。

    c.逐行对比前后两天的数据,检查md5(concat(全部有可能变化的字段))是否相同(low)

    d.要求业务数据库提供变动流水(人品,颜值)

    (2)因为ods_user_info本身导入过来就是新增变动明细的表,所以不用处理

    a)数据库中新增2020-06-15一天的数据

    b)通过Sqoop把2020-06-15日所有数据导入

    mysql_to_hdfs.sh all 2020-06-15

    c)ods层数据导入

    hdfs_to_ods_db.sh all 2020-06-15

    步骤2:先合并变动信息,再追加新增信息,插入到临时表中

    1)建立临时表

    1. drop table if exists dwd_dim_user_info_his_tmp;
    2. create external table dwd_dim_user_info_his_tmp(
    3. `id` string COMMENT '用户id',
    4. `name` string COMMENT '姓名',
    5. `birthday` string COMMENT '生日',
    6. `gender` string COMMENT '性别',
    7. `email` string COMMENT '邮箱',
    8. `user_level` string COMMENT '用户等级',
    9. `create_time` string COMMENT '创建时间',
    10. `operate_time` string COMMENT '操作时间',
    11. `start_date` string COMMENT '有效开始日期',
    12. `end_date` string COMMENT '有效结束日期'
    13. ) COMMENT '订单拉链临时表'
    14. stored as parquet
    15. location '/warehouse/gmall/dwd/dwd_dim_user_info_his_tmp/'
    16. tblproperties ("parquet.compression"="lzo");

    2)导入脚本

    1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    2. insert overwrite table dwd_dim_user_info_his_tmp
    3. select * from
    4. (
    5. select --获取的是新增和变化的数据
    6. id,
    7. name,
    8. birthday,
    9. gender,
    10. email,
    11. user_level,
    12. create_time,
    13. operate_time,
    14. '2020-06-15' start_date,--加上两列
    15. '9999-99-99' end_date
    16. from ods_user_info where dt='2020-06-15'
    17. union all --union代表的是进行去重,union进行拼接
    18. select
    19. uh.id,
    20. uh.name,
    21. uh.birthday,
    22. uh.gender,
    23. uh.email,
    24. uh.user_level,
    25. uh.create_time,
    26. uh.operate_time,
    27. uh.start_date,
    28. if(ui.id is not null and uh.end_date='9999-99-99', date_add(ui.dt,-1), uh.end_date) end_date
    29. from dwd_dim_user_info_his uh left join
    30. (
    31. select
    32. *
    33. from ods_user_info
    34. where dt='2020-06-15'
    35. ) ui on uh.id=ui.id
    36. )his
    37. order by his.id, start_date;

    新的知识点-------------------------横向拼接用join,纵向拼接用union all

    步骤3:把临时表覆盖给拉链表

    1)导入数据

    insert overwrite table dwd_dim_user_info_his select * from dwd_dim_user_info_his_tmp;

    2)查询导入数据

    select id, start_date, end_date from dwd_dim_user_info_his limit 2;

    五十二.DWD_业务导入脚本

    写脚本的五个步骤:
    ①#!/bin/bash
    ②定义变量
    ③获取时间
    ④sql语句 sql=" "遇到表, ${APP}/$do_date 遇到时间, 自定义函数需要加上${APP}
    ⑤执行sql(执行索引)

    1.编写脚本

    1)在/home/atguigu/bin目录下创建脚本ods_to_dwd_db.sh
    vim ods_to_dwd_db.sh

    在脚本中填写如下内容:
    地区表只导入一次,时间表手动上传一次,用户拉链表:临时表 初始化拉链表(只能第一次手动导入,不能够在脚本里面第一次导入)

    1. #!/bin/bash
    2. APP=gmall
    3. hive=/opt/module/hive/bin/hive
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$2" ] ;then
    6. do_date=$2
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql1="
    11. set mapreduce.job.queuename=hive;
    12. set hive.exec.dynamic.partition.mode=nonstrict;
    13. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
    14. insert overwrite table ${APP}.dwd_dim_sku_info partition(dt='$do_date')
    15. select
    16. sku.id,
    17. sku.spu_id,
    18. sku.price,
    19. sku.sku_name,
    20. sku.sku_desc,
    21. sku.weight,
    22. sku.tm_id,
    23. ob.tm_name,
    24. sku.category3_id,
    25. c2.id category2_id,
    26. c1.id category1_id,
    27. c3.name category3_name,
    28. c2.name category2_name,
    29. c1.name category1_name,
    30. spu.spu_name,
    31. sku.create_time
    32. from
    33. (
    34. select * from ${APP}.ods_sku_info where dt='$do_date'
    35. )sku
    36. join
    37. (
    38. select * from ${APP}.ods_base_trademark where dt='$do_date'
    39. )ob on sku.tm_id=ob.tm_id
    40. join
    41. (
    42. select * from ${APP}.ods_spu_info where dt='$do_date'
    43. )spu on spu.id = sku.spu_id
    44. join
    45. (
    46. select * from ${APP}.ods_base_category3 where dt='$do_date'
    47. )c3 on sku.category3_id=c3.id
    48. join
    49. (
    50. select * from ${APP}.ods_base_category2 where dt='$do_date'
    51. )c2 on c3.category2_id=c2.id
    52. join
    53. (
    54. select * from ${APP}.ods_base_category1 where dt='$do_date'
    55. )c1 on c2.category1_id=c1.id;
    56. insert overwrite table ${APP}.dwd_dim_coupon_info partition(dt='$do_date')
    57. select
    58. id,
    59. coupon_name,
    60. coupon_type,
    61. condition_amount,
    62. condition_num,
    63. activity_id,
    64. benefit_amount,
    65. benefit_discount,
    66. create_time,
    67. range_type,
    68. spu_id,
    69. tm_id,
    70. category3_id,
    71. limit_num,
    72. operate_time,
    73. expire_time
    74. from ${APP}.ods_coupon_info
    75. where dt='$do_date';
    76. insert overwrite table ${APP}.dwd_dim_activity_info partition(dt='$do_date')
    77. select
    78. id,
    79. activity_name,
    80. activity_type,
    81. start_time,
    82. end_time,
    83. create_time
    84. from ${APP}.ods_activity_info
    85. where dt='$do_date';
    86. insert overwrite table ${APP}.dwd_fact_order_detail partition(dt='$do_date')
    87. select
    88. id,
    89. order_id,
    90. user_id,
    91. sku_id,
    92. sku_num,
    93. order_price,
    94. sku_num,
    95. create_time,
    96. province_id,
    97. source_type,
    98. source_id,
    99. original_amount_d,
    100. if(rn=1,final_total_amount-(sum_div_final_amount-final_amount_d),final_amount_d),
    101. if(rn=1,feight_fee-(sum_div_feight_fee-feight_fee_d),feight_fee_d),
    102. if(rn=1,benefit_reduce_amount-(sum_div_benefit_reduce_amount-benefit_reduce_amount_d),benefit_reduce_amount_d)
    103. from
    104. (
    105. select
    106. od.id,
    107. od.order_id,
    108. od.user_id,
    109. od.sku_id,
    110. od.sku_name,
    111. od.order_price,
    112. od.sku_num,
    113. od.create_time,
    114. oi.province_id,
    115. od.source_type,
    116. od.source_id,
    117. round(od.order_price*od.sku_num,2) original_amount_d,
    118. round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2) final_amount_d,
    119. round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2) feight_fee_d,
    120. round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2) benefit_reduce_amount_d,
    121. row_number() over(partition by od.order_id order by od.id desc) rn,
    122. oi.final_total_amount,
    123. oi.feight_fee,
    124. oi.benefit_reduce_amount,
    125. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2)) over(partition by od.order_id) sum_div_final_amount,
    126. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2)) over(partition by od.order_id) sum_div_feight_fee,
    127. sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2)) over(partition by od.order_id) sum_div_benefit_reduce_amount
    128. from
    129. (
    130. select * from ${APP}.ods_order_detail where dt='$do_date'
    131. ) od
    132. join
    133. (
    134. select * from ${APP}.ods_order_info where dt='$do_date'
    135. ) oi
    136. on od.order_id=oi.id
    137. )t1;
    138. insert overwrite table ${APP}.dwd_fact_payment_info partition(dt='$do_date')
    139. select
    140. pi.id,
    141. pi.out_trade_no,
    142. pi.order_id,
    143. pi.user_id,
    144. pi.alipay_trade_no,
    145. pi.total_amount,
    146. pi.subject,
    147. pi.payment_type,
    148. pi.payment_time,
    149. oi.province_id
    150. from
    151. (
    152. select * from ${APP}.ods_payment_info where dt='$do_date'
    153. )pi
    154. join
    155. (
    156. select id, province_id from ${APP}.ods_order_info where dt='$do_date'
    157. )oi
    158. on pi.order_id = oi.id;
    159. insert overwrite table ${APP}.dwd_fact_order_refund_info partition(dt='$do_date')
    160. select
    161. id,
    162. user_id,
    163. order_id,
    164. sku_id,
    165. refund_type,
    166. refund_num,
    167. refund_amount,
    168. refund_reason_type,
    169. create_time
    170. from ${APP}.ods_order_refund_info
    171. where dt='$do_date';
    172. insert overwrite table ${APP}.dwd_fact_comment_info partition(dt='$do_date')
    173. select
    174. id,
    175. user_id,
    176. sku_id,
    177. spu_id,
    178. order_id,
    179. appraise,
    180. create_time
    181. from ${APP}.ods_comment_info
    182. where dt='$do_date';
    183. insert overwrite table ${APP}.dwd_fact_cart_info partition(dt='$do_date')
    184. select
    185. id,
    186. user_id,
    187. sku_id,
    188. cart_price,
    189. sku_num,
    190. sku_name,
    191. create_time,
    192. operate_time,
    193. is_ordered,
    194. order_time,
    195. source_type,
    196. source_id
    197. from ${APP}.ods_cart_info
    198. where dt='$do_date';
    199. insert overwrite table ${APP}.dwd_fact_favor_info partition(dt='$do_date')
    200. select
    201. id,
    202. user_id,
    203. sku_id,
    204. spu_id,
    205. is_cancel,
    206. create_time,
    207. cancel_time
    208. from ${APP}.ods_favor_info
    209. where dt='$do_date';
    210. insert overwrite table ${APP}.dwd_fact_coupon_use partition(dt)
    211. select
    212. if(new.id is null,old.id,new.id),
    213. if(new.coupon_id is null,old.coupon_id,new.coupon_id),
    214. if(new.user_id is null,old.user_id,new.user_id),
    215. if(new.order_id is null,old.order_id,new.order_id),
    216. if(new.coupon_status is null,old.coupon_status,new.coupon_status),
    217. if(new.get_time is null,old.get_time,new.get_time),
    218. if(new.using_time is null,old.using_time,new.using_time),
    219. if(new.used_time is null,old.used_time,new.used_time),
    220. date_format(if(new.get_time is null,old.get_time,new.get_time),'yyyy-MM-dd')
    221. from
    222. (
    223. select
    224. id,
    225. coupon_id,
    226. user_id,
    227. order_id,
    228. coupon_status,
    229. get_time,
    230. using_time,
    231. used_time
    232. from ${APP}.dwd_fact_coupon_use
    233. where dt in
    234. (
    235. select
    236. date_format(get_time,'yyyy-MM-dd')
    237. from ${APP}.ods_coupon_use
    238. where dt='$do_date'
    239. )
    240. )old
    241. full outer join
    242. (
    243. select
    244. id,
    245. coupon_id,
    246. user_id,
    247. order_id,
    248. coupon_status,
    249. get_time,
    250. using_time,
    251. used_time
    252. from ${APP}.ods_coupon_use
    253. where dt='$do_date'
    254. )new
    255. on old.id=new.id;
    256. insert overwrite table ${APP}.dwd_fact_order_info partition(dt)
    257. select
    258. if(new.id is null,old.id,new.id),
    259. if(new.order_status is null,old.order_status,new.order_status),
    260. if(new.user_id is null,old.user_id,new.user_id),
    261. if(new.out_trade_no is null,old.out_trade_no,new.out_trade_no),
    262. if(new.tms['1001'] is null,old.create_time,new.tms['1001']),--1001对应未支付状态
    263. if(new.tms['1002'] is null,old.payment_time,new.tms['1002']),
    264. if(new.tms['1003'] is null,old.cancel_time,new.tms['1003']),
    265. if(new.tms['1004'] is null,old.finish_time,new.tms['1004']),
    266. if(new.tms['1005'] is null,old.refund_time,new.tms['1005']),
    267. if(new.tms['1006'] is null,old.refund_finish_time,new.tms['1006']),
    268. if(new.province_id is null,old.province_id,new.province_id),
    269. if(new.activity_id is null,old.activity_id,new.activity_id),
    270. if(new.original_total_amount is null,old.original_total_amount,new.original_total_amount),
    271. if(new.benefit_reduce_amount is null,old.benefit_reduce_amount,new.benefit_reduce_amount),
    272. if(new.feight_fee is null,old.feight_fee,new.feight_fee),
    273. if(new.final_total_amount is null,old.final_total_amount,new.final_total_amount),
    274. date_format(if(new.tms['1001'] is null,old.create_time,new.tms['1001']),'yyyy-MM-dd')
    275. from
    276. (
    277. select
    278. id,
    279. order_status,
    280. user_id,
    281. out_trade_no,
    282. create_time,
    283. payment_time,
    284. cancel_time,
    285. finish_time,
    286. refund_time,
    287. refund_finish_time,
    288. province_id,
    289. activity_id,
    290. original_total_amount,
    291. benefit_reduce_amount,
    292. feight_fee,
    293. final_total_amount
    294. from ${APP}.dwd_fact_order_info
    295. where dt
    296. in
    297. (
    298. select
    299. date_format(create_time,'yyyy-MM-dd')
    300. from ${APP}.ods_order_info
    301. where dt='$do_date'
    302. )
    303. )old
    304. full outer join
    305. (
    306. select
    307. info.id,
    308. info.order_status,
    309. info.user_id,
    310. info.out_trade_no,
    311. info.province_id,
    312. act.activity_id,
    313. log.tms,
    314. info.original_total_amount,
    315. info.benefit_reduce_amount,
    316. info.feight_fee,
    317. info.final_total_amount
    318. from
    319. (
    320. select
    321. order_id,
    322. str_to_map(concat_ws(',',collect_set(concat(order_status,'=',operate_time))),',','=') tms
    323. from ${APP}.ods_order_status_log
    324. where dt='$do_date'
    325. group by order_id
    326. )log
    327. join
    328. (
    329. select * from ${APP}.ods_order_info where dt='$do_date'
    330. )info
    331. on log.order_id=info.id
    332. left join
    333. (
    334. select * from ${APP}.ods_activity_order where dt='$do_date'
    335. )act
    336. on log.order_id=act.order_id
    337. )new
    338. on old.id=new.id;
    339. "
    340. sql2="
    341. insert overwrite table ${APP}.dwd_dim_base_province
    342. select
    343. bp.id,
    344. bp.name,
    345. bp.area_code,
    346. bp.iso_code,
    347. bp.region_id,
    348. br.region_name
    349. from ${APP}.ods_base_province bp
    350. join ${APP}.ods_base_region br
    351. on bp.region_id=br.id;
    352. "
    353. sql3="
    354. insert overwrite table ${APP}.dwd_dim_user_info_his_tmp
    355. select * from
    356. (
    357. select
    358. id,
    359. name,
    360. birthday,
    361. gender,
    362. email,
    363. user_level,
    364. create_time,
    365. operate_time,
    366. '$do_date' start_date,
    367. '9999-99-99' end_date
    368. from ${APP}.ods_user_info where dt='$do_date'
    369. union all
    370. select
    371. uh.id,
    372. uh.name,
    373. uh.birthday,
    374. uh.gender,
    375. uh.email,
    376. uh.user_level,
    377. uh.create_time,
    378. uh.operate_time,
    379. uh.start_date,
    380. if(ui.id is not null and uh.end_date='9999-99-99', date_add(ui.dt,-1), uh.end_date) end_date
    381. from ${APP}.dwd_dim_user_info_his uh left join
    382. (
    383. select
    384. *
    385. from ${APP}.ods_user_info
    386. where dt='$do_date'
    387. ) ui on uh.id=ui.id
    388. )his
    389. order by his.id, start_date;
    390. insert overwrite table ${APP}.dwd_dim_user_info_his
    391. select * from ${APP}.dwd_dim_user_info_his_tmp;
    392. "
    393. case $1 in
    394. "first"){
    395. $hive -e "$sql1$sql2"
    396. };;
    397. "all"){
    398. $hive -e "$sql1$sql3"
    399. };;
    400. esac

    初次导入时,脚本的第一个参数应为first,线上环境不传第二个参数,自动获取前一天日期。

    [atguigu@hadoop102 bin]$ ods_to_dwd_db.sh first 2020-06-14

    每日定时导入,脚本的第一个参数应为all,线上环境不传第二个参数,自动获取前一天日期。

    [atguigu@hadoop102 bin]$ ods_to_dwd_db.sh all 2020-06-15

    五十三.DWS层_DWT层

    站在维度的角度去看待事实.

    五十四.DWS_DWT层术语

    1)用户

    用户以设备为判断标准,在移动统计中,每个独立设备认为是一个独立用户。Android系统根据IMEI号,IOS系统根据OpenUDID来标识一个独立用户,每部手机一个用户。

    2)新增用户

    首次联网使用应用的用户。如果一个用户首次打开某APP,那这个用户定义为新增用户;卸载再安装的设备,不会被算作一次新增。新增用户包括日新增用户、周新增用户、月新增用户。

    3)活跃用户

    打开应用的用户即为活跃用户,不考虑用户的使用情况。每天一台设备打开多次会被计为一个活跃用户。

    4)周活跃用户(用户活跃要去重)

    某个自然周(月)内启动过应用的用户,该周(月)内的多次启动只记一个活跃用户。

    5)月活跃

    月活跃用户与截止到该月累计的用户总和之间的比例。

    6)沉默用户

    用户仅在安装当天(次日)启动一次,后续时间无再启动行为。该指标可以反映新增用户质量和用户与APP的匹配程度。

    7)版本分布

    不同版本的周内各天新增用户数,活跃用户数和启动次数。利于判断APP各个版本之间的优劣和用户行为习惯。

    8)本周回流用户

    上周未启动过应用,本周启动了应用的用户。

    9)连续n周活跃用户

    连续n周,每周至少启动一次。

    10)忠诚用户

    连续活跃5周以上的用户

    11)连续活跃用户

    连续2周及以上活跃的用户

    12)近期流失用户

    连续n(2<= n <= 4)周没有启动应用的用户。(第n+1周没有启动过)

    13)留存用户

    某段时间内的新增用户,经过一段时间后,仍然使用应用的被认作是留存用户;这部分用户占当时新增用户的比例即是留存率。

    例如,5月份新增用户200,这200人在6月份启动过应用的有100人,7月份启动过应用的有80人,8月份启动过应用的有50人;则5月份新增用户一个月后的留存率是50%,二个月后的留存率是40%,三个月后的留存率是25%。

    14)用户新鲜度

    每天启动应用的新老用户比例,即新增用户数占活跃用户数的比例。

    15)单次使用时长

    每次启动使用的时间长度。

    16)日使用时长

    累计一天内的使用时间长度。

    17)启动次数计算标准

    IOS平台应用退到后台就算一次独立的启动;Android平台我们规定,两次启动之间的间隔小于30秒,被计算一次启动。用户在使用过程中,若因收发短信或接电话等退出应用30秒又再次返回应用中,那这两次行为应该是延续而非独立的,所以可以被算作一次使用行为,即一次启动。业内大多使用30秒这个标准,但用户还是可以自定义此时间间隔。

    五十五.DWS_DWT层系统函数

    一. nvl函数

    1)基本语法

    NVL(表达式1,表达式2)

    如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值。

    该函数的目的是把一个空值(null)转换成一个实际的值。其表达式的值可以是数字型、字符型和日期型但是表达式1和表达式2的数据类型必须为同一个类型

    2)案例实操

    1. hive (gmall)> select nvl(1,0);
    2. 1
    3. hive (gmall)> select nvl(null,"hello");
    4. hello

    二. 日期处理函数

    1)date_format函数(根据格式整理日期)

    hive (gmall)> select date_format('2020-06-14','yyyy-MM');

    2020-06

    2)date_add函数(加减日期) 其功能和date_sub函数的功能是相同的

    hive (gmall)> select date_add('2020-06-14',-1);

    2020-06-13

    hive (gmall)> select date_add('2020-06-14',1);

    2020-06-15

    3)next_day函数

    (1)取当前天的下一个周的周一

    hive (gmall)> select next_day('2020-06-14','MO');

    2020-06-15

    说明:星期一到星期日的英文(Monday,Tuesday、Wednesday、Thursday、Friday、Saturday、Sunday)

    (2)取当前周的周一

    hive (gmall)> select date_add(next_day('2020-06-14','MO'),-7);

    2020-06-8

    4)last_day函数(求当月最后一天日期)

    hive (gmall)> select last_day('2020-06-14');

    2020-06-30

    五十六.DWS_DWT层复杂数据类型

    1)map结构数据定义

    map<string,string>------这里是相应的k v类型进行存储

    2)array结构数据定义

    array

    3)struct结构数据定义

    struct

    4)struct和array嵌套定义(比较常见的)

    array>

    五十七.DWS层设备行为宽表分析

     1)建表语句

    1. drop table if exists dws_uv_detail_daycount;
    2. create external table dws_uv_detail_daycount
    3. (
    4. `mid_id` string COMMENT '设备id',
    5. `brand` string COMMENT '手机品牌',
    6. `model` string COMMENT '手机型号',
    7. `login_count` bigint COMMENT '活跃次数',
    8. `page_stats` array<struct<page_id:string,page_count:bigint>> COMMENT '页面访问统计'
    9. ) COMMENT '每日设备行为表'
    10. partitioned by(dt string)
    11. stored as parquet
    12. location '/warehouse/gmall/dws/dws_uv_detail_daycount'
    13. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. with
    2. tmp_start as
    3. (
    4. select
    5. mid_id,
    6. brand,
    7. model,
    8. count(*) login_count
    9. from dwd_start_log
    10. where dt='2020-06-14'
    11. group by mid_id,brand,model
    12. ),
    13. tmp_page as
    14. (
    15. select
    16. mid_id,
    17. brand,
    18. model, collect_set(named_struct('page_id',page_id,'page_count',page_count)) page_stats
    19. from
    20. (
    21. select
    22. mid_id,
    23. brand,
    24. model,
    25. page_id,
    26. count(*) page_count
    27. from dwd_page_log
    28. where dt='2020-06-14'
    29. group by mid_id,brand,model,page_id
    30. )tmp
    31. group by mid_id,brand,model
    32. )
    33. insert overwrite table dws_uv_detail_daycount partition(dt='2020-06-14')
    34. select
    35. nvl(tmp_start.mid_id,tmp_page.mid_id),
    36. nvl(tmp_start.brand,tmp_page.brand),
    37. nvl(tmp_start.model,tmp_page.model),
    38. tmp_start.login_count,
    39. tmp_page.page_stats
    40. from tmp_start
    41. full outer join tmp_page
    42. on tmp_start.mid_id=tmp_page.mid_id
    43. and tmp_start.brand=tmp_page.brand
    44. and tmp_start.model=tmp_page.model;

    首先在用户活动表dw_start_log之中进行提取,提取出来相应的活跃次数,group by之中只能够存在三类信息,一类是字段信息,一类是常量,最后一种是聚合函数。
    由page_stats之中的信息可以知道,我们这个地方是提取array之中的东西,一个一个进行提取,进而得到更多的信息,进行一个聚合操作。这里的字段是在dwd_page_log之中进行提取, page_id, count(*) page_count在这个地方的操作是将其进行相应的聚合处理,collect_set在这里的使用1上面的东西进行相应的一个聚合的过程,使得在使用的过程之中是非常好用的。collect_set(named_struct('page_id',page_id,'page_count',page_count))之中的name_struct使用是将里面的东西按照行的方式进行一个存储,可以指定里面的名称,如果要是struct的话就是一个按照col存储的过程,不能够使用名称进行指定。

    上面使用的with start_tmp as是创建一个临时表的过程,只有在使用第一个的时候是使用with *** as,其余的时候是使用*** as,可以直接省略as。

    这里使用full outer join是将两端的信息都进行一个保全的过程。

    3)查询加载结果

    select * from dws_uv_detail_daycount where dt='2020-06-14' limit 2;

    五十八.DWT层设备行为宽表完成

    如何写出sql?
    sql by里面只能有三个类型:字段 常量 聚合函数

    处理累积类型指标:
    先找出旧表数据(当前表) 找出新表数据(在当前层的下一层),再使用join操作,有新的取出新的,没有新的取出旧的。

    1)建表语句

    1. drop table if exists dwt_uv_topic;
    2. create external table dwt_uv_topic
    3. (
    4. `mid_id` string comment '设备id',
    5. `brand` string comment '手机品牌',
    6. `model` string comment '手机型号',
    7. `login_date_first` string comment '首次活跃时间',
    8. `login_date_last` string comment '末次活跃时间',
    9. `login_day_count` bigint comment '当日活跃次数',
    10. `login_count` bigint comment '累积活跃天数'
    11. ) COMMENT '设备主题宽表'
    12. stored as parquet
    13. location '/warehouse/gmall/dwt/dwt_uv_topic'
    14. tblproperties ("parquet.compression"="lzo");

    旧表概念就是在当前一天的所有数据,累积型表都是full outer join,进行连接下一层的数据。

    首次活跃,使用旧的数据进行判断,末次使用新的数据进行判断。

     2)数据装载

    1. insert overwrite table dwt_uv_topic
    2. select
    3. nvl(new.mid_id,old.mid_id),
    4. nvl(new.model,old.model),
    5. nvl(new.brand,old.brand),
    6. if(old.mid_id is null,'2020-06-14',old.login_date_first),
    7. if(new.mid_id is not null,'2020-06-14',old.login_date_last),
    8. if(new.mid_id is not null, new.login_count,0),
    9. nvl(old.login_count,0)+if(new.login_count>0,1,0)
    10. from
    11. (
    12. select
    13. *
    14. from dwt_uv_topic
    15. )old
    16. full outer join
    17. (
    18. select
    19. *
    20. from dws_uv_detail_daycount
    21. where dt='2020-06-14'
    22. )new
    23. on old.mid_id=new.mid_id;

    上面的old就是当前的表,新的表是下一层的dws层,里面含有相应的时间

    3)查询加载结果

    hive (gmall)> select * from dwt_uv_topic limit 5;

    五十九.DWS层_会员行为宽表分析

    1)建表语句

    1. drop table if exists dws_user_action_daycount;
    2. create external table dws_user_action_daycount
    3. (
    4. user_id string comment '用户 id',
    5. login_count bigint comment '登录次数',
    6. cart_count bigint comment '加入购物车次数',
    7. order_count bigint comment '下单次数',
    8. order_amount decimal(16,2) comment '下单金额',
    9. payment_count bigint comment '支付次数',
    10. payment_amount decimal(16,2) comment '支付金额',
    11. order_detail_stats array<struct<sku_id:string,sku_num:bigint,order_count:bigint,order_amount:decimal(20,2)>> comment '下单明细统计'
    12. ) COMMENT '每日会员行为'
    13. PARTITIONED BY (`dt` string)
    14. stored as parquet
    15. location '/warehouse/gmall/dws/dws_user_action_daycount/'
    16. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. select
    2. user_id,
    3. count(*) login_count
    4. from dwd_start_log
    5. where dt='2020-06-14'
    6. and user_id is not null
    7. group by user_id;

    使用上面代码先是进行测试了一下,结果如下是可以正常运行的。

    1. with
    2. tmp_login as
    3. (
    4. select
    5. user_id,
    6. count(*) login_count
    7. from dwd_start_log
    8. where dt='2020-06-14'
    9. and user_id is not null
    10. group by user_id
    11. ),
    12. tmp_cart as
    13. (
    14. select
    15. user_id,
    16. count(*) cart_count
    17. from dwd_action_log
    18. where dt='2020-06-14'
    19. and user_id is not null
    20. and action_id='cart_add'
    21. group by user_id
    22. ),tmp_order as
    23. (
    24. select
    25. user_id,
    26. count(*) order_count,
    27. sum(final_total_amount) order_amount
    28. from dwd_fact_order_info
    29. where dt='2020-06-14'
    30. group by user_id
    31. ) ,
    32. tmp_payment as
    33. (
    34. select
    35. user_id,
    36. count(*) payment_count,
    37. sum(payment_amount) payment_amount
    38. from dwd_fact_payment_info
    39. where dt='2020-06-14'
    40. group by user_id
    41. ),
    42. tmp_order_detail as
    43. (
    44. select
    45. user_id,
    46. collect_set(named_struct('sku_id',sku_id,'sku_num',sku_num,'order_count',order_count,'order_amount',order_amount)) order_stats
    47. from
    48. (
    49. select
    50. user_id,
    51. sku_id,
    52. sum(sku_num) sku_num,
    53. count(*) order_count,
    54. cast(sum(final_amount_d) as decimal(20,2)) order_amount
    55. from dwd_fact_order_detail
    56. where dt='2020-06-14'
    57. group by user_id,sku_id
    58. )tmp
    59. group by user_id
    60. )
    61. insert overwrite table dws_user_action_daycount partition(dt='2020-06-14')
    62. select
    63. tmp_login.user_id,
    64. login_count,
    65. nvl(cart_count,0),
    66. nvl(order_count,0),
    67. nvl(order_amount,0.0),
    68. nvl(payment_count,0),
    69. nvl(payment_amount,0.0),
    70. order_stats
    71. from tmp_login
    72. left join tmp_cart on tmp_login.user_id=tmp_cart.user_id
    73. left join tmp_order on tmp_login.user_id=tmp_order.user_id
    74. left join tmp_payment on tmp_login.user_id=tmp_payment.user_id
    75. left join tmp_order_detail on tmp_login.user_id=tmp_order_detail.user_id;

    3)查询加载结果

    hive (gmall)> select * from dws_user_action_daycount where dt='2020-06-14' limit 2;

    六十.DWT层_会员行为宽表完成

    1)建表语句

    1. drop table if exists dwt_user_topic;
    2. create external table dwt_user_topic
    3. (
    4. user_id string comment '用户id',
    5. login_date_first string comment '首次登录时间',
    6. login_date_last string comment '末次登录时间',
    7. login_count bigint comment '累积登录天数',
    8. login_last_30d_count bigint comment '最近30日登录天数',
    9. order_date_first string comment '首次下单时间',
    10. order_date_last string comment '末次下单时间',
    11. order_count bigint comment '累积下单次数',
    12. order_amount decimal(16,2) comment '累积下单金额',
    13. order_last_30d_count bigint comment '最近30日下单次数',
    14. order_last_30d_amount bigint comment '最近30日下单金额',
    15. payment_date_first string comment '首次支付时间',
    16. payment_date_last string comment '末次支付时间',
    17. payment_count decimal(16,2) comment '累积支付次数',
    18. payment_amount decimal(16,2) comment '累积支付金额',
    19. payment_last_30d_count decimal(16,2) comment '最近30日支付次数',
    20. payment_last_30d_amount decimal(16,2) comment '最近30日支付金额'
    21. )COMMENT '会员主题宽表'
    22. stored as parquet
    23. location '/warehouse/gmall/dwt/dwt_user_topic/'
    24. tblproperties ("parquet.compression"="lzo");

     2)数据装载

    1. insert overwrite table dwt_user_topic
    2. select
    3. nvl(new.user_id,old.user_id),
    4. if(old.login_date_first is null and new.login_count>0,'2020-06-14',old.login_date_first),
    5. if(new.login_count>0,'2020-06-14',old.login_date_last),
    6. nvl(old.login_count,0)+if(new.login_count>0,1,0),
    7. nvl(new.login_last_30d_count,0),
    8. if(old.order_date_first is null and new.order_count>0,'2020-06-14',old.order_date_first),
    9. if(new.order_count>0,'2020-06-14',old.order_date_last),
    10. nvl(old.order_count,0)+nvl(new.order_count,0),
    11. nvl(old.order_amount,0)+nvl(new.order_amount,0),
    12. nvl(new.order_last_30d_count,0),
    13. nvl(new.order_last_30d_amount,0),
    14. if(old.payment_date_first is null and new.payment_count>0,'2020-06-14',old.payment_date_first),
    15. if(new.payment_count>0,'2020-06-14',old.payment_date_last),
    16. nvl(old.payment_count,0)+nvl(new.payment_count,0),
    17. nvl(old.payment_amount,0)+nvl(new.payment_amount,0),
    18. nvl(new.payment_last_30d_count,0),
    19. nvl(new.payment_last_30d_amount,0)
    20. from
    21. dwt_user_topic old
    22. full outer join
    23. (
    24. select
    25. user_id,
    26. sum(if(dt='2020-06-14',login_count,0)) login_count,
    27. sum(if(dt='2020-06-14',order_count,0)) order_count,
    28. sum(if(dt='2020-06-14',order_amount,0)) order_amount,
    29. sum(if(dt='2020-06-14',payment_count,0)) payment_count,
    30. sum(if(dt='2020-06-14',payment_amount,0)) payment_amount,
    31. sum(if(login_count>0,1,0)) login_last_30d_count,
    32. sum(order_count) order_last_30d_count,
    33. sum(order_amount) order_last_30d_amount,
    34. sum(payment_count) payment_last_30d_count,
    35. sum(payment_amount) payment_last_30d_amount
    36. from dws_user_action_daycount
    37. where dt>=date_add( '2020-06-14',-30)
    38. group by user_id
    39. )new
    40. on old.user_id=new.user_id;

    3)查询加载结果
    hive (gmall)> select * from dwt_user_topic limit 5;

    六十一.数据仓库小总结

    1)ODS
    ①保持数据原貌不做任何修改;
    ②创建分区表;
    ③采用LZO压缩;

    2)DWD
    ①清洗工具:HQL spark sql python mr kettle
    ②清洗规则:空值 重复数据 过期数据 解析
    ③清洗掉多少数据算正常 万分之一
    ④采用LZO压缩
    ⑤采用列式存储
    ⑥创建分区表
    ⑦维度退化(维度建模 星形模型)
    ⑧建模
    选择业务=》声明粒度=》确定维度=》确定事实
    全部选择   保持最小粒度   时间 用户 地点 活动 优惠券 商品(进行相应的维度退化)  确定事实表(次数 个数 件数 金额)

    3)DWS=》粒度是天
    表:时间 用户 商品 地点 活动 优惠券
    字段:站在维度的角度去看待事实,去看待相应的度量值

    4)DWT=》粒度是从事件开始到结束
    表:时间 用户 商品 地点 活动 优惠券
    字段:站在维度的角度去看待事实,关注开始 结束 度量值的累积值 一段时间的累计值

    5)ADS统计指标

    六十二.数据仓库_宽表回顾

    如果要是不存在DWS和DWT是可以的,因为存在DWD层,DWD层的信息是足够明细的。DWS和DWT层是为了为了提高表的复用性。后面所谓的需求是为了做统计,就是将相应的数据做一个聚合的过程,有的东西是需要需要进行好多步骤,然后分析得到最终的结果。
    DWS和DWT就是将进行重复计算的数据放到一个表之中,这就是相应的宽表的意义。
    主题宽表就是什么主题就是什么东西,宽表之中就是所有的和事实表相关的东西。这个表为什么要这样进行设计,因为这样设计是和后面的需求有关系的,就是为了方便统计各个指标。一个维度字段和一个度量值。这里的宽表并不是万能的,只能应对一些常见的需求,并不能应对万能的需求。

    每天进行更新的时候,并不是将DWS所有的都进行聚合,DWT存在的意义就是将增加的数据与新的DWS进行一个累加的过程。 

    六十三.DWS_商品主题每日统计

    1)建表语句

    1. drop table if exists dws_sku_action_daycount;
    2. create external table dws_sku_action_daycount
    3. (
    4. sku_id string comment 'sku_id',
    5. order_count bigint comment '被下单次数',
    6. order_num bigint comment '被下单件数',
    7. order_amount decimal(16,2) comment '被下单金额',
    8. payment_count bigint comment '被支付次数',
    9. payment_num bigint comment '被支付件数',
    10. payment_amount decimal(16,2) comment '被支付金额',
    11. refund_count bigint comment '被退款次数',
    12. refund_num bigint comment '被退款件数',
    13. refund_amount decimal(16,2) comment '被退款金额',
    14. cart_count bigint comment '被加入购物车次数',
    15. favor_count bigint comment '被收藏次数',
    16. appraise_good_count bigint comment '好评数',
    17. appraise_mid_count bigint comment '中评数',
    18. appraise_bad_count bigint comment '差评数',
    19. appraise_default_count bigint comment '默认评价数'
    20. ) COMMENT '每日商品行为'
    21. PARTITIONED BY (`dt` string)
    22. stored as parquet
    23. location '/warehouse/gmall/dws/dws_sku_action_daycount/'
    24. tblproperties ("parquet.compression"="lzo");

    前三个实在相应的订单详情的字段之中找到。

    2)数据装载

    注意:如果是23点59下单,支付日期跨天。需要从订单详情里面取出支付时间是今天,且订单时间是昨天或者今天的订单。

    1. with
    2. tmp_order as
    3. (
    4. ---包含支付的订单也包含未支付的订单
    5. select
    6. sku_id,
    7. count(*) order_count, ---直接使用count*)就可以拿到下单次数
    8. sum(sku_num) order_num, ---商品支付的件数
    9. sum(final_amount_d) order_amount ---商品支付的最终金额(统一按照最终金额算)
    10. from dwd_fact_order_detail
    11. where dt='2020-06-14' --- 过滤,按照当天的数据算
    12. group by sku_id
    13. ),
    14. tmp_payment as
    15. (
    16. ---支付的订单
    17. select
    18. sku_id,
    19. count(*) payment_count,
    20. sum(sku_num) payment_num,
    21. sum(final_amount_d) payment_amount
    22. from dwd_fact_order_detail
    23. where dt='2020-06-14'
    24. and order_id in
    25. (
    26. select
    27. id
    28. from dwd_fact_order_info
    29. where (dt='2020-06-14'
    30. or dt=date_add('2020-06-14',-1)) ---进行了订单
    31. and date_format(payment_time,'yyyy-MM-dd')='2020-06-14' ---进行了支付
    32. )
    33. group by sku_id
    34. ),
    35. tmp_refund as
    36. (
    37. select
    38. sku_id,
    39. count(*) refund_count,
    40. sum(refund_num) refund_num,
    41. sum(refund_amount) refund_amount
    42. from dwd_fact_order_refund_info
    43. where dt='2020-06-14'
    44. group by sku_id
    45. ),
    46. tmp_cart as
    47. (
    48. select
    49. item sku_id,
    50. count(*) cart_count
    51. from dwd_action_log
    52. where dt='2020-06-14'
    53. and user_id is not null
    54. and action_id='cart_add'
    55. group by item
    56. ),tmp_favor as
    57. (
    58. select
    59. item sku_id,
    60. count(*) favor_count
    61. from dwd_action_log
    62. where dt='2020-06-14'
    63. and user_id is not null
    64. and action_id='favor_add'
    65. group by item
    66. ),
    67. tmp_appraise as
    68. (
    69. select
    70. sku_id,
    71. sum(if(appraise='1201',1,0)) appraise_good_count,
    72. sum(if(appraise='1202',1,0)) appraise_mid_count,
    73. sum(if(appraise='1203',1,0)) appraise_bad_count,
    74. sum(if(appraise='1204',1,0)) appraise_default_count
    75. from dwd_fact_comment_info
    76. where dt='2020-06-14'
    77. group by sku_id
    78. )
    79. insert overwrite table dws_sku_action_daycount partition(dt='2020-06-14')
    80. select
    81. sku_id,
    82. sum(order_count),
    83. sum(order_num),
    84. sum(order_amount),
    85. sum(payment_count),
    86. sum(payment_num),
    87. sum(payment_amount),
    88. sum(refund_count),
    89. sum(refund_num),
    90. sum(refund_amount),
    91. sum(cart_count),
    92. sum(favor_count),
    93. sum(appraise_good_count),
    94. sum(appraise_mid_count),
    95. sum(appraise_bad_count),
    96. sum(appraise_default_count)
    97. from
    98. (
    99. select
    100. sku_id,
    101. order_count,
    102. order_num,
    103. order_amount,
    104. 0 payment_count,
    105. 0 payment_num,
    106. 0 payment_amount,
    107. 0 refund_count,
    108. 0 refund_num,
    109. 0 refund_amount,
    110. 0 cart_count,
    111. 0 favor_count,
    112. 0 appraise_good_count,
    113. 0 appraise_mid_count,
    114. 0 appraise_bad_count,
    115. 0 appraise_default_count
    116. from tmp_order
    117. union all
    118. select
    119. sku_id,
    120. 0 order_count,
    121. 0 order_num,
    122. 0 order_amount,
    123. payment_count,
    124. payment_num,
    125. payment_amount,
    126. 0 refund_count,
    127. 0 refund_num,
    128. 0 refund_amount,
    129. 0 cart_count,
    130. 0 favor_count,
    131. 0 appraise_good_count,
    132. 0 appraise_mid_count,
    133. 0 appraise_bad_count,
    134. 0 appraise_default_count
    135. from tmp_payment
    136. union all
    137. select
    138. sku_id,
    139. 0 order_count,
    140. 0 order_num,
    141. 0 order_amount,
    142. 0 payment_count,
    143. 0 payment_num,
    144. 0 payment_amount,
    145. refund_count,
    146. refund_num,
    147. refund_amount,
    148. 0 cart_count,
    149. 0 favor_count,
    150. 0 appraise_good_count,
    151. 0 appraise_mid_count,
    152. 0 appraise_bad_count,
    153. 0 appraise_default_count
    154. from tmp_refund
    155. union all
    156. select
    157. sku_id,
    158. 0 order_count,
    159. 0 order_num,
    160. 0 order_amount,
    161. 0 payment_count,
    162. 0 payment_num,
    163. 0 payment_amount,
    164. 0 refund_count,
    165. 0 refund_num,
    166. 0 refund_amount,
    167. cart_count,
    168. 0 favor_count,
    169. 0 appraise_good_count,
    170. 0 appraise_mid_count,
    171. 0 appraise_bad_count,
    172. 0 appraise_default_count
    173. from tmp_cart
    174. union all
    175. select
    176. sku_id,
    177. 0 order_count,
    178. 0 order_num,
    179. 0 order_amount,
    180. 0 payment_count,
    181. 0 payment_num,
    182. 0 payment_amount,
    183. 0 refund_count,
    184. 0 refund_num,
    185. 0 refund_amount,
    186. 0 cart_count,
    187. favor_count,
    188. 0 appraise_good_count,
    189. 0 appraise_mid_count,
    190. 0 appraise_bad_count,
    191. 0 appraise_default_count
    192. from tmp_favor
    193. union all
    194. select
    195. sku_id,
    196. 0 order_count,
    197. 0 order_num,
    198. 0 order_amount,
    199. 0 payment_count,
    200. 0 payment_num,
    201. 0 payment_amount,
    202. 0 refund_count,
    203. 0 refund_num,
    204. 0 refund_amount,
    205. 0 cart_count,
    206. 0 favor_count,
    207. appraise_good_count,
    208. appraise_mid_count,
    209. appraise_bad_count,
    210. appraise_default_count
    211. from tmp_appraise
    212. )tmp
    213. group by sku_id;

    上面的with as是为了声明子查询,使用left join是左边有的,加上右边有的,并且上面的操作是使用补零的操作进行联合。

    3)查询加载结果

    hive (gmall)>

    select * from dws_sku_action_daycount where dt='2020-06-14' limit 2;

    六十四.DWT_商品主题宽表_数据装载

    1)建表语句

    1. drop table if exists dwt_sku_topic;
    2. create external table dwt_sku_topic
    3. (
    4. sku_id string comment 'sku_id',
    5. spu_id string comment 'spu_id',
    6. order_last_30d_count bigint comment '最近30日被下单次数',
    7. order_last_30d_num bigint comment '最近30日被下单件数',
    8. order_last_30d_amount decimal(16,2) comment '最近30日被下单金额',
    9. order_count bigint comment '累积被下单次数',
    10. order_num bigint comment '累积被下单件数',
    11. order_amount decimal(16,2) comment '累积被下单金额',
    12. payment_last_30d_count bigint comment '最近30日被支付次数',
    13. payment_last_30d_num bigint comment '最近30日被支付件数',
    14. payment_last_30d_amount decimal(16,2) comment '最近30日被支付金额',
    15. payment_count bigint comment '累积被支付次数',
    16. payment_num bigint comment '累积被支付件数',
    17. payment_amount decimal(16,2) comment '累积被支付金额',
    18. refund_last_30d_count bigint comment '最近三十日退款次数',
    19. refund_last_30d_num bigint comment '最近三十日退款件数',
    20. refund_last_30d_amount decimal(16,2) comment '最近三十日退款金额',
    21. refund_count bigint comment '累积退款次数',
    22. refund_num bigint comment '累积退款件数',
    23. refund_amount decimal(16,2) comment '累积退款金额',
    24. cart_last_30d_count bigint comment '最近30日被加入购物车次数',
    25. cart_count bigint comment '累积被加入购物车次数',
    26. favor_last_30d_count bigint comment '最近30日被收藏次数',
    27. favor_count bigint comment '累积被收藏次数',
    28. appraise_last_30d_good_count bigint comment '最近30日好评数',
    29. appraise_last_30d_mid_count bigint comment '最近30日中评数',
    30. appraise_last_30d_bad_count bigint comment '最近30日差评数',
    31. appraise_last_30d_default_count bigint comment '最近30日默认评价数',
    32. appraise_good_count bigint comment '累积好评数',
    33. appraise_mid_count bigint comment '累积中评数',
    34. appraise_bad_count bigint comment '累积差评数',
    35. appraise_default_count bigint comment '累积默认评价数'
    36. )COMMENT '商品主题宽表'
    37. stored as parquet
    38. location '/warehouse/gmall/dwt/dwt_sku_topic/'
    39. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. insert overwrite table dwt_sku_topic
    2. select
    3. nvl(new.sku_id,old.sku_id),
    4. sku_info.spu_id,
    5. nvl(new.order_count30,0),
    6. nvl(new.order_num30,0),
    7. nvl(new.order_amount30,0),
    8. nvl(old.order_count,0) + nvl(new.order_count,0),
    9. nvl(old.order_num,0) + nvl(new.order_num,0),
    10. nvl(old.order_amount,0) + nvl(new.order_amount,0),
    11. nvl(new.payment_count30,0),
    12. nvl(new.payment_num30,0),
    13. nvl(new.payment_amount30,0),
    14. nvl(old.payment_count,0) + nvl(new.payment_count,0),
    15. nvl(old.payment_num,0) + nvl(new.payment_count,0),
    16. nvl(old.payment_amount,0) + nvl(new.payment_count,0),
    17. nvl(new.refund_count30,0),
    18. nvl(new.refund_num30,0),
    19. nvl(new.refund_amount30,0),
    20. nvl(old.refund_count,0) + nvl(new.refund_count,0),
    21. nvl(old.refund_num,0) + nvl(new.refund_num,0),
    22. nvl(old.refund_amount,0) + nvl(new.refund_amount,0),
    23. nvl(new.cart_count30,0),
    24. nvl(old.cart_count,0) + nvl(new.cart_count,0),
    25. nvl(new.favor_count30,0),
    26. nvl(old.favor_count,0) + nvl(new.favor_count,0),
    27. nvl(new.appraise_good_count30,0),
    28. nvl(new.appraise_mid_count30,0),
    29. nvl(new.appraise_bad_count30,0),
    30. nvl(new.appraise_default_count30,0) ,
    31. nvl(old.appraise_good_count,0) + nvl(new.appraise_good_count,0),
    32. nvl(old.appraise_mid_count,0) + nvl(new.appraise_mid_count,0),
    33. nvl(old.appraise_bad_count,0) + nvl(new.appraise_bad_count,0),
    34. nvl(old.appraise_default_count,0) + nvl(new.appraise_default_count,0)
    35. from
    36. dwt_sku_topic old
    37. full outer join
    38. (
    39. select
    40. sku_id,
    41. sum(if(dt='2020-06-14', order_count,0 )) order_count,
    42. sum(if(dt='2020-06-14',order_num ,0 )) order_num,
    43. sum(if(dt='2020-06-14',order_amount,0 )) order_amount ,
    44. sum(if(dt='2020-06-14',payment_count,0 )) payment_count,
    45. sum(if(dt='2020-06-14',payment_num,0 )) payment_num,
    46. sum(if(dt='2020-06-14',payment_amount,0 )) payment_amount,
    47. sum(if(dt='2020-06-14',refund_count,0 )) refund_count,
    48. sum(if(dt='2020-06-14',refund_num,0 )) refund_num,
    49. sum(if(dt='2020-06-14',refund_amount,0 )) refund_amount,
    50. sum(if(dt='2020-06-14',cart_count,0 )) cart_count,
    51. sum(if(dt='2020-06-14',favor_count,0 )) favor_count,
    52. sum(if(dt='2020-06-14',appraise_good_count,0 )) appraise_good_count,
    53. sum(if(dt='2020-06-14',appraise_mid_count,0 ) ) appraise_mid_count ,
    54. sum(if(dt='2020-06-14',appraise_bad_count,0 )) appraise_bad_count,
    55. sum(if(dt='2020-06-14',appraise_default_count,0 )) appraise_default_count,
    56. sum(order_count) order_count30 ,
    57. sum(order_num) order_num30,
    58. sum(order_amount) order_amount30,
    59. sum(payment_count) payment_count30,
    60. sum(payment_num) payment_num30,
    61. sum(payment_amount) payment_amount30,
    62. sum(refund_count) refund_count30,
    63. sum(refund_num) refund_num30,
    64. sum(refund_amount) refund_amount30,
    65. sum(cart_count) cart_count30,
    66. sum(favor_count) favor_count30,
    67. sum(appraise_good_count) appraise_good_count30,
    68. sum(appraise_mid_count) appraise_mid_count30,
    69. sum(appraise_bad_count) appraise_bad_count30,
    70. sum(appraise_default_count) appraise_default_count30
    71. from dws_sku_action_daycount
    72. where dt >= date_add ('2020-06-14', -30)
    73. group by sku_id
    74. )new
    75. on new.sku_id = old.sku_id
    76. left join
    77. (select * from dwd_dim_sku_info where dt='2020-06-14') sku_info
    78. on nvl(new.sku_id,old.sku_id)= sku_info.id;

    上面的构建的思路也是使用普通的叠加的操作,拿到的数据和之前的数据进行相加。
    有一个小细节,上面的spu_id和去拿到?需要和商品维度表进行一个join

    六十五.DWS_活动每日统计宽表

    1)建表语句

    1. drop table if exists dwt_activity_topic;
    2. create external table dwt_activity_topic(
    3. `id` string COMMENT '编号',
    4. `activity_name` string COMMENT '活动名称',
    5. `activity_type` string COMMENT '活动类型',
    6. `start_time` string COMMENT '开始时间',
    7. `end_time` string COMMENT '结束时间',
    8. `create_time` string COMMENT '创建时间',
    9. `display_day_count` bigint COMMENT '当日曝光次数',
    10. `order_day_count` bigint COMMENT '当日下单次数',
    11. `order_day_amount` decimal(20,2) COMMENT '当日下单金额',
    12. `payment_day_count` bigint COMMENT '当日支付次数',
    13. `payment_day_amount` decimal(20,2) COMMENT '当日支付金额',
    14. `display_count` bigint COMMENT '累积曝光次数',
    15. `order_count` bigint COMMENT '累积下单次数',
    16. `order_amount` decimal(20,2) COMMENT '累积下单金额',
    17. `payment_count` bigint COMMENT '累积支付次数',
    18. `payment_amount` decimal(20,2) COMMENT '累积支付金额'
    19. ) COMMENT '活动主题宽表'
    20. stored as parquet
    21. location '/warehouse/gmall/dwt/dwt_activity_topic/'
    22. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. with
    2. tmp_op as
    3. (
    4. select
    5. activity_id,
    6. sum(if(date_format(create_time,'yyyy-MM-dd')='2020-06-14',1,0)) order_count,
    7. sum(if(date_format(create_time,'yyyy-MM-dd')='2020-06-14',final_total_amount,0)) order_amount,---统计14号的订单金额总额
    8. sum(if(date_format(payment_time,'yyyy-MM-dd')='2020-06-14',1,0)) payment_count,
    9. sum(if(date_format(payment_time,'yyyy-MM-dd')='2020-06-14',final_total_amount,0)) payment_amount
    10. from dwd_fact_order_info
    11. where (dt='2020-06-14' or dt=date_add('2020-06-14',-1))
    12. and activity_id is not null --- 过滤没有参加活动的订单
    13. group by activity_id
    14. ),
    15. tmp_display as
    16. (
    17. select
    18. item activity_id,
    19. count(*) display_count
    20. from dwd_display_log
    21. where dt='2020-06-14'
    22. and item_type='activity_id'
    23. group by item
    24. ),
    25. tmp_activity as
    26. (
    27. select
    28. *
    29. from dwd_dim_activity_info
    30. where dt='2020-06-14'
    31. )
    32. insert overwrite table dws_activity_info_daycount partition(dt='2020-06-14')
    33. select
    34. nvl(tmp_op.activity_id,tmp_display.activity_id),
    35. tmp_activity.activity_name,
    36. tmp_activity.activity_type,
    37. tmp_activity.start_time,
    38. tmp_activity.end_time,
    39. tmp_activity.create_time,
    40. tmp_display.display_count,
    41. tmp_op.order_count,
    42. tmp_op.order_amount,
    43. tmp_op.payment_count,
    44. tmp_op.payment_amount
    45. from tmp_op
    46. full outer join tmp_display on tmp_op.activity_id=tmp_display.activity_id
    47. left join tmp_activity on nvl(tmp_op.activity_id,tmp_display.activity_id)=tmp_activity.id;

    3)查询加载结果

    hive (gmall)>

    select * from dws_activity_info_daycount where dt='2020-06-14' limit 2

    六十六.DWT_活动主题宽表

    1)建表语句

    1. drop table if exists dwt_activity_topic;
    2. create external table dwt_activity_topic(
    3. `id` string COMMENT '编号',
    4. `activity_name` string COMMENT '活动名称',
    5. `activity_type` string COMMENT '活动类型',
    6. `start_time` string COMMENT '开始时间',
    7. `end_time` string COMMENT '结束时间',
    8. `create_time` string COMMENT '创建时间',
    9. `display_day_count` bigint COMMENT '当日曝光次数',
    10. `order_day_count` bigint COMMENT '当日下单次数',
    11. `order_day_amount` decimal(20,2) COMMENT '当日下单金额',
    12. `payment_day_count` bigint COMMENT '当日支付次数',
    13. `payment_day_amount` decimal(20,2) COMMENT '当日支付金额',
    14. `display_count` bigint COMMENT '累积曝光次数',
    15. `order_count` bigint COMMENT '累积下单次数',
    16. `order_amount` decimal(20,2) COMMENT '累积下单金额',
    17. `payment_count` bigint COMMENT '累积支付次数',
    18. `payment_amount` decimal(20,2) COMMENT '累积支付金额'
    19. ) COMMENT '活动主题宽表'
    20. stored as parquet
    21. location '/warehouse/gmall/dwt/dwt_activity_topic/'
    22. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. insert overwrite table dwt_activity_topic
    2. select
    3. nvl(new.id,old.id),
    4. nvl(new.activity_name,old.activity_name),
    5. nvl(new.activity_type,old.activity_type),
    6. nvl(new.start_time,old.start_time),
    7. nvl(new.end_time,old.end_time),
    8. nvl(new.create_time,old.create_time),
    9. nvl(new.display_count,0),
    10. nvl(new.order_count,0),
    11. nvl(new.order_amount,0.0),
    12. nvl(new.payment_count,0),
    13. nvl(new.payment_amount,0.0),
    14. nvl(new.display_count,0)+nvl(old.display_count,0),
    15. nvl(new.order_count,0)+nvl(old.order_count,0),
    16. nvl(new.order_amount,0.0)+nvl(old.order_amount,0.0),
    17. nvl(new.payment_count,0)+nvl(old.payment_count,0),
    18. nvl(new.payment_amount,0.0)+nvl(old.payment_amount,0.0)
    19. from
    20. (
    21. select
    22. *
    23. from dwt_activity_topic
    24. )old
    25. full outer join
    26. (
    27. select
    28. *
    29. from dws_activity_info_daycount
    30. where dt='2020-06-14'
    31. )new
    32. on old.id=new.id;

    3)查询加载结果

    hive (gmall)> select * from dwt_activity_topic limit 5;

    六十七.DWS-DWT_地区主题表

    1)建表语句

    1. drop table if exists dws_area_stats_daycount;
    2. create external table dws_area_stats_daycount(
    3. `id` bigint COMMENT '编号',
    4. `province_name` string COMMENT '省份名称',
    5. `area_code` string COMMENT '地区编码',
    6. `iso_code` string COMMENT 'iso编码',
    7. `region_id` string COMMENT '地区ID',
    8. `region_name` string COMMENT '地区名称',
    9. `login_count` string COMMENT '活跃设备数',
    10. `order_count` bigint COMMENT '下单次数',
    11. `order_amount` decimal(20,2) COMMENT '下单金额',
    12. `payment_count` bigint COMMENT '支付次数',
    13. `payment_amount` decimal(20,2) COMMENT '支付金额'
    14. ) COMMENT '每日地区统计表'
    15. PARTITIONED BY (`dt` string)
    16. stored as parquet
    17. location '/warehouse/gmall/dws/dws_area_stats_daycount/'
    18. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. with
    2. tmp_login as
    3. (
    4. select
    5. area_code,
    6. count(*) login_count
    7. from dwd_start_log
    8. where dt='2020-06-14'
    9. group by area_code
    10. ),
    11. tmp_op as
    12. (
    13. select
    14. province_id,
    15. sum(if(date_format(create_time,'yyyy-MM-dd')='2020-06-14',1,0)) order_count,
    16. sum(if(date_format(create_time,'yyyy-MM-dd')='2020-06-14',final_total_amount,0)) order_amount,
    17. sum(if(date_format(payment_time,'yyyy-MM-dd')='2020-06-14',1,0)) payment_count,
    18. sum(if(date_format(payment_time,'yyyy-MM-dd')='2020-06-14',final_total_amount,0)) payment_amount
    19. from dwd_fact_order_info
    20. where (dt='2020-06-14' or dt=date_add('2020-06-14',-1))
    21. group by province_id
    22. )
    23. insert overwrite table dws_area_stats_daycount partition(dt='2020-06-14')
    24. select
    25. pro.id,
    26. pro.province_name,
    27. pro.area_code,
    28. pro.iso_code,
    29. pro.region_id,
    30. pro.region_name,
    31. nvl(tmp_login.login_count,0),
    32. nvl(tmp_op.order_count,0),
    33. nvl(tmp_op.order_amount,0.0),
    34. nvl(tmp_op.payment_count,0),
    35. nvl(tmp_op.payment_amount,0.0)
    36. from dwd_dim_base_province pro
    37. left join tmp_login on pro.area_code=tmp_login.area_code
    38. left join tmp_op on pro.id=tmp_op.province_id;

    1)建表语句

    1. drop table if exists dwt_area_topic;
    2. create external table dwt_area_topic(
    3. `id` bigint COMMENT '编号',
    4. `province_name` string COMMENT '省份名称',
    5. `area_code` string COMMENT '地区编码',
    6. `iso_code` string COMMENT 'iso编码',
    7. `region_id` string COMMENT '地区ID',
    8. `region_name` string COMMENT '地区名称',
    9. `login_day_count` string COMMENT '当天活跃设备数',
    10. `login_last_30d_count` string COMMENT '最近30天活跃设备数',
    11. `order_day_count` bigint COMMENT '当天下单次数',
    12. `order_day_amount` decimal(16,2) COMMENT '当天下单金额',
    13. `order_last_30d_count` bigint COMMENT '最近30天下单次数',
    14. `order_last_30d_amount` decimal(16,2) COMMENT '最近30天下单金额',
    15. `payment_day_count` bigint COMMENT '当天支付次数',
    16. `payment_day_amount` decimal(16,2) COMMENT '当天支付金额',
    17. `payment_last_30d_count` bigint COMMENT '最近30天支付次数',
    18. `payment_last_30d_amount` decimal(16,2) COMMENT '最近30天支付金额'
    19. ) COMMENT '地区主题宽表'
    20. stored as parquet
    21. location '/warehouse/gmall/dwt/dwt_area_topic/'
    22. tblproperties ("parquet.compression"="lzo");

    2)数据装载

    1. insert overwrite table dwt_area_topic
    2. select
    3. nvl(old.id,new.id),
    4. nvl(old.province_name,new.province_name),
    5. nvl(old.area_code,new.area_code),
    6. nvl(old.iso_code,new.iso_code),
    7. nvl(old.region_id,new.region_id),
    8. nvl(old.region_name,new.region_name),
    9. nvl(new.login_day_count,0),
    10. nvl(new.login_last_30d_count,0),
    11. nvl(new.order_day_count,0),
    12. nvl(new.order_day_amount,0.0),
    13. nvl(new.order_last_30d_count,0),
    14. nvl(new.order_last_30d_amount,0.0),
    15. nvl(new.payment_day_count,0),
    16. nvl(new.payment_day_amount,0.0),
    17. nvl(new.payment_last_30d_count,0),
    18. nvl(new.payment_last_30d_amount,0.0)
    19. from
    20. (
    21. select
    22. *
    23. from dwt_area_topic
    24. )old
    25. full outer join
    26. (
    27. select
    28. id,
    29. province_name,
    30. area_code,
    31. iso_code,
    32. region_id,
    33. region_name,
    34. sum(if(dt='2020-06-14',login_count,0)) login_day_count,
    35. sum(if(dt='2020-06-14',order_count,0)) order_day_count,
    36. sum(if(dt='2020-06-14',order_amount,0.0)) order_day_amount,
    37. sum(if(dt='2020-06-14',payment_count,0)) payment_day_count,
    38. sum(if(dt='2020-06-14',payment_amount,0.0)) payment_day_amount,
    39. sum(login_count) login_last_30d_count,
    40. sum(order_count) order_last_30d_count,
    41. sum(order_amount) order_last_30d_amount,
    42. sum(payment_count) payment_last_30d_count,
    43. sum(payment_amount) payment_last_30d_amount
    44. from dws_area_stats_daycount
    45. where dt>=date_add('2020-06-14',-30)
    46. group by id,province_name,area_code,iso_code,region_id,region_name
    47. )new
    48. on old.id=new.id;

    3)查询加载结果

    hive (gmall)> select * from dwt_area_topic limit 5;

    六十八.DWS_DWT数据导入脚本

    A.DWS数据导入脚本

    1)在/home/atguigu/bin目录下创建脚本dwd_to_dws.sh

    [atguigu@hadoop102 bin]$ vim dwd_to_dws.sh

    1. #!/bin/bash
    2. APP=gmall
    3. hive=/opt/module/hive/bin/hive
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$1" ] ;then
    6. do_date=$1
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql="
    11. set mapreduce.job.queuename=hive;
    12. with
    13. tmp_start as
    14. (
    15. select
    16. mid_id,
    17. brand,
    18. model,
    19. count(*) login_count
    20. from ${APP}.dwd_start_log
    21. where dt='$do_date'
    22. group by mid_id,brand,model
    23. ),
    24. tmp_page as
    25. (
    26. select
    27. mid_id,
    28. brand,
    29. model,
    30. collect_set(named_struct('page_id',page_id,'page_count',page_count)) page_stats
    31. from
    32. (
    33. select
    34. mid_id,
    35. brand,
    36. model,
    37. page_id,
    38. count(*) page_count
    39. from ${APP}.dwd_page_log
    40. where dt='$do_date'
    41. group by mid_id,brand,model,page_id
    42. )tmp
    43. group by mid_id,brand,model
    44. )
    45. insert overwrite table ${APP}.dws_uv_detail_daycount partition(dt='$do_date')
    46. select
    47. nvl(tmp_start.mid_id,tmp_page.mid_id),
    48. nvl(tmp_start.brand,tmp_page.brand),
    49. nvl(tmp_start.model,tmp_page.model),
    50. tmp_start.login_count,
    51. tmp_page.page_stats
    52. from tmp_start
    53. full outer join tmp_page
    54. on tmp_start.mid_id=tmp_page.mid_id
    55. and tmp_start.brand=tmp_page.brand
    56. and tmp_start.model=tmp_page.model;
    57. with
    58. tmp_login as
    59. (
    60. select
    61. user_id,
    62. count(*) login_count
    63. from ${APP}.dwd_start_log
    64. where dt='$do_date'
    65. and user_id is not null
    66. group by user_id
    67. ),
    68. tmp_cart as
    69. (
    70. select
    71. user_id,
    72. count(*) cart_count
    73. from ${APP}.dwd_action_log
    74. where dt='$do_date'
    75. and user_id is not null
    76. and action_id='cart_add'
    77. group by user_id
    78. ),tmp_order as
    79. (
    80. select
    81. user_id,
    82. count(*) order_count,
    83. sum(final_total_amount) order_amount
    84. from ${APP}.dwd_fact_order_info
    85. where dt='$do_date'
    86. group by user_id
    87. ) ,
    88. tmp_payment as
    89. (
    90. select
    91. user_id,
    92. count(*) payment_count,
    93. sum(payment_amount) payment_amount
    94. from ${APP}.dwd_fact_payment_info
    95. where dt='$do_date'
    96. group by user_id
    97. ),
    98. tmp_order_detail as
    99. (
    100. select
    101. user_id,
    102. collect_set(named_struct('sku_id',sku_id,'sku_num',sku_num,'order_count',order_count,'order_amount',order_amount)) order_stats
    103. from
    104. (
    105. select
    106. user_id,
    107. sku_id,
    108. sum(sku_num) sku_num,
    109. count(*) order_count,
    110. cast(sum(final_amount_d) as decimal(20,2)) order_amount
    111. from ${APP}.dwd_fact_order_detail
    112. where dt='$do_date'
    113. group by user_id,sku_id
    114. )tmp
    115. group by user_id
    116. )
    117. insert overwrite table ${APP}.dws_user_action_daycount partition(dt='$do_date')
    118. select
    119. tmp_login.user_id,
    120. login_count,
    121. nvl(cart_count,0),
    122. nvl(order_count,0),
    123. nvl(order_amount,0.0),
    124. nvl(payment_count,0),
    125. nvl(payment_amount,0.0),
    126. order_stats
    127. from tmp_login
    128. left outer join tmp_cart on tmp_login.user_id=tmp_cart.user_id
    129. left outer join tmp_order on tmp_login.user_id=tmp_order.user_id
    130. left outer join tmp_payment on tmp_login.user_id=tmp_payment.user_id
    131. left outer join tmp_order_detail on tmp_login.user_id=tmp_order_detail.user_id;
    132. with
    133. tmp_order as
    134. (
    135. select
    136. sku_id,
    137. count(*) order_count,
    138. sum(sku_num) order_num,
    139. sum(final_amount_d) order_amount
    140. from ${APP}.dwd_fact_order_detail
    141. where dt='$do_date'
    142. group by sku_id
    143. ),
    144. tmp_payment as
    145. (
    146. select
    147. sku_id,
    148. count(*) payment_count,
    149. sum(sku_num) payment_num,
    150. sum(final_amount_d) payment_amount
    151. from ${APP}.dwd_fact_order_detail
    152. where dt='$do_date'
    153. and order_id in
    154. (
    155. select
    156. id
    157. from ${APP}.dwd_fact_order_info
    158. where (dt='$do_date'
    159. or dt=date_add('$do_date',-1))
    160. and date_format(payment_time,'yyyy-MM-dd')='$do_date'
    161. )
    162. group by sku_id
    163. ),
    164. tmp_refund as
    165. (
    166. select
    167. sku_id,
    168. count(*) refund_count,
    169. sum(refund_num) refund_num,
    170. sum(refund_amount) refund_amount
    171. from ${APP}.dwd_fact_order_refund_info
    172. where dt='$do_date'
    173. group by sku_id
    174. ),
    175. tmp_cart as
    176. (
    177. select
    178. item sku_id,
    179. count(*) cart_count
    180. from ${APP}.dwd_action_log
    181. where dt='$do_date'
    182. and user_id is not null
    183. and action_id='cart_add'
    184. group by item
    185. ),tmp_favor as
    186. (
    187. select
    188. item sku_id,
    189. count(*) favor_count
    190. from ${APP}.dwd_action_log
    191. where dt='$do_date'
    192. and user_id is not null
    193. and action_id='favor_add'
    194. group by item
    195. ),
    196. tmp_appraise as
    197. (
    198. select
    199. sku_id,
    200. sum(if(appraise='1201',1,0)) appraise_good_count,
    201. sum(if(appraise='1202',1,0)) appraise_mid_count,
    202. sum(if(appraise='1203',1,0)) appraise_bad_count,
    203. sum(if(appraise='1204',1,0)) appraise_default_count
    204. from ${APP}.dwd_fact_comment_info
    205. where dt='$do_date'
    206. group by sku_id
    207. )
    208. insert overwrite table ${APP}.dws_sku_action_daycount partition(dt='$do_date')
    209. select
    210. sku_id,
    211. sum(order_count),
    212. sum(order_num),
    213. sum(order_amount),
    214. sum(payment_count),
    215. sum(payment_num),
    216. sum(payment_amount),
    217. sum(refund_count),
    218. sum(refund_num),
    219. sum(refund_amount),
    220. sum(cart_count),
    221. sum(favor_count),
    222. sum(appraise_good_count),
    223. sum(appraise_mid_count),
    224. sum(appraise_bad_count),
    225. sum(appraise_default_count)
    226. from
    227. (
    228. select
    229. sku_id,
    230. order_count,
    231. order_num,
    232. order_amount,
    233. 0 payment_count,
    234. 0 payment_num,
    235. 0 payment_amount,
    236. 0 refund_count,
    237. 0 refund_num,
    238. 0 refund_amount,
    239. 0 cart_count,
    240. 0 favor_count,
    241. 0 appraise_good_count,
    242. 0 appraise_mid_count,
    243. 0 appraise_bad_count,
    244. 0 appraise_default_count
    245. from tmp_order
    246. union all
    247. select
    248. sku_id,
    249. 0 order_count,
    250. 0 order_num,
    251. 0 order_amount,
    252. payment_count,
    253. payment_num,
    254. payment_amount,
    255. 0 refund_count,
    256. 0 refund_num,
    257. 0 refund_amount,
    258. 0 cart_count,
    259. 0 favor_count,
    260. 0 appraise_good_count,
    261. 0 appraise_mid_count,
    262. 0 appraise_bad_count,
    263. 0 appraise_default_count
    264. from tmp_payment
    265. union all
    266. select
    267. sku_id,
    268. 0 order_count,
    269. 0 order_num,
    270. 0 order_amount,
    271. 0 payment_count,
    272. 0 payment_num,
    273. 0 payment_amount,
    274. refund_count,
    275. refund_num,
    276. refund_amount,
    277. 0 cart_count,
    278. 0 favor_count,
    279. 0 appraise_good_count,
    280. 0 appraise_mid_count,
    281. 0 appraise_bad_count,
    282. 0 appraise_default_count
    283. from tmp_refund
    284. union all
    285. select
    286. sku_id,
    287. 0 order_count,
    288. 0 order_num,
    289. 0 order_amount,
    290. 0 payment_count,
    291. 0 payment_num,
    292. 0 payment_amount,
    293. 0 refund_count,
    294. 0 refund_num,
    295. 0 refund_amount,
    296. cart_count,
    297. 0 favor_count,
    298. 0 appraise_good_count,
    299. 0 appraise_mid_count,
    300. 0 appraise_bad_count,
    301. 0 appraise_default_count
    302. from tmp_cart
    303. union all
    304. select
    305. sku_id,
    306. 0 order_count,
    307. 0 order_num,
    308. 0 order_amount,
    309. 0 payment_count,
    310. 0 payment_num,
    311. 0 payment_amount,
    312. 0 refund_count,
    313. 0 refund_num,
    314. 0 refund_amount,
    315. 0 cart_count,
    316. favor_count,
    317. 0 appraise_good_count,
    318. 0 appraise_mid_count,
    319. 0 appraise_bad_count,
    320. 0 appraise_default_count
    321. from tmp_favor
    322. union all
    323. select
    324. sku_id,
    325. 0 order_count,
    326. 0 order_num,
    327. 0 order_amount,
    328. 0 payment_count,
    329. 0 payment_num,
    330. 0 payment_amount,
    331. 0 refund_count,
    332. 0 refund_num,
    333. 0 refund_amount,
    334. 0 cart_count,
    335. 0 favor_count,
    336. appraise_good_count,
    337. appraise_mid_count,
    338. appraise_bad_count,
    339. appraise_default_count
    340. from tmp_appraise
    341. )tmp
    342. group by sku_id;
    343. with
    344. tmp_login as
    345. (
    346. select
    347. area_code,
    348. count(*) login_count
    349. from ${APP}.dwd_start_log
    350. where dt='$do_date'
    351. group by area_code
    352. ),
    353. tmp_op as
    354. (
    355. select
    356. province_id,
    357. sum(if(date_format(create_time,'yyyy-MM-dd')='$do_date',1,0)) order_count,
    358. sum(if(date_format(create_time,'yyyy-MM-dd')='$do_date',final_total_amount,0)) order_amount,
    359. sum(if(date_format(payment_time,'yyyy-MM-dd')='$do_date',1,0)) payment_count,
    360. sum(if(date_format(payment_time,'yyyy-MM-dd')='$do_date',final_total_amount,0)) payment_amount
    361. from ${APP}.dwd_fact_order_info
    362. where (dt='$do_date' or dt=date_add('$do_date',-1))
    363. group by province_id
    364. )
    365. insert overwrite table ${APP}.dws_area_stats_daycount partition(dt='$do_date')
    366. select
    367. pro.id,
    368. pro.province_name,
    369. pro.area_code,
    370. pro.iso_code,
    371. pro.region_id,
    372. pro.region_name,
    373. nvl(tmp_login.login_count,0),
    374. nvl(tmp_op.order_count,0),
    375. nvl(tmp_op.order_amount,0.0),
    376. nvl(tmp_op.payment_count,0),
    377. nvl(tmp_op.payment_amount,0.0)
    378. from ${APP}.dwd_dim_base_province pro
    379. left join tmp_login on pro.area_code=tmp_login.area_code
    380. left join tmp_op on pro.id=tmp_op.province_id;
    381. with
    382. tmp_op as
    383. (
    384. select
    385. activity_id,
    386. sum(if(date_format(create_time,'yyyy-MM-dd')='$do_date',1,0)) order_count,
    387. sum(if(date_format(create_time,'yyyy-MM-dd')='$do_date',final_total_amount,0)) order_amount,
    388. sum(if(date_format(payment_time,'yyyy-MM-dd')='$do_date',1,0)) payment_count,
    389. sum(if(date_format(payment_time,'yyyy-MM-dd')='$do_date',final_total_amount,0)) payment_amount
    390. from ${APP}.dwd_fact_order_info
    391. where (dt='$do_date' or dt=date_add('$do_date',-1))
    392. and activity_id is not null
    393. group by activity_id
    394. ),
    395. tmp_display as
    396. (
    397. select
    398. item activity_id,
    399. count(*) display_count
    400. from ${APP}.dwd_display_log
    401. where dt='$do_date'
    402. and item_type='activity_id'
    403. group by item
    404. ),
    405. tmp_activity as
    406. (
    407. select
    408. *
    409. from ${APP}.dwd_dim_activity_info
    410. where dt='$do_date'
    411. )
    412. insert overwrite table ${APP}.dws_activity_info_daycount partition(dt='$do_date')
    413. select
    414. nvl(tmp_op.activity_id,tmp_display.activity_id),
    415. tmp_activity.activity_name,
    416. tmp_activity.activity_type,
    417. tmp_activity.start_time,
    418. tmp_activity.end_time,
    419. tmp_activity.create_time,
    420. tmp_display.display_count,
    421. tmp_op.order_count,
    422. tmp_op.order_amount,
    423. tmp_op.payment_count,
    424. tmp_op.payment_amount
    425. from tmp_op
    426. full outer join tmp_display on tmp_op.activity_id=tmp_display.activity_id
    427. left join tmp_activity on nvl(tmp_op.activity_id,tmp_display.activity_id)=tmp_activity.id;
    428. "
    429. $hive -e "$sql"

    2)增加脚本执行权限
    [atguigu@hadoop102 bin]$ chmod 777 dwd_to_dws.sh

    3)执行脚本导入数据
    [atguigu@hadoop102 bin]$ dwd_to_dws.sh 2020-06-15

    4)查看导入数据
    hive (gmall)> 
    select * from dws_uv_detail_daycount where dt='2020-06-15' limit 2;
    select * from
    dws_user_action_daycount where dt='2020-06-15' limit 2;
    select * from dws_sku_action_daycount where dt='2020-06-15' limit 2;
    select * from dws_activity_info_daycount where dt='2020-06-15' limit 2;
    select * from dws_area_stats_daycount where dt='2020-06-15' limit 2;

    B.DWT数据导入脚本

    1)在/home/atguigu/bin目录下创建脚本dws_to_dwt.sh

    [atguigu@hadoop102 bin]$ vim dws_to_dwt.sh

    1. #!/bin/bash
    2. APP=gmall
    3. hive=/opt/module/hive/bin/hive
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$1" ] ;then
    6. do_date=$1
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql="
    11. set mapreduce.job.queuename=hive;
    12. insert overwrite table ${APP}.dwt_uv_topic
    13. select
    14. nvl(new.mid_id,old.mid_id),
    15. nvl(new.model,old.model),
    16. nvl(new.brand,old.brand),
    17. if(old.mid_id is null,'$do_date',old.login_date_first),
    18. if(new.mid_id is not null,'$do_date',old.login_date_last),
    19. if(new.mid_id is not null, new.login_count,0),
    20. nvl(old.login_count,0)+if(new.login_count>0,1,0)
    21. from
    22. (
    23. select
    24. *
    25. from ${APP}.dwt_uv_topic
    26. )old
    27. full outer join
    28. (
    29. select
    30. *
    31. from ${APP}.dws_uv_detail_daycount
    32. where dt='$do_date'
    33. )new
    34. on old.mid_id=new.mid_id;
    35. insert overwrite table ${APP}.dwt_user_topic
    36. select
    37. nvl(new.user_id,old.user_id),
    38. if(old.login_date_first is null and new.login_count>0,'$do_date',old.login_date_first),
    39. if(new.login_count>0,'$do_date',old.login_date_last),
    40. nvl(old.login_count,0)+if(new.login_count>0,1,0),
    41. nvl(new.login_last_30d_count,0),
    42. if(old.order_date_first is null and new.order_count>0,'$do_date',old.order_date_first),
    43. if(new.order_count>0,'$do_date',old.order_date_last),
    44. nvl(old.order_count,0)+nvl(new.order_count,0),
    45. nvl(old.order_amount,0)+nvl(new.order_amount,0),
    46. nvl(new.order_last_30d_count,0),
    47. nvl(new.order_last_30d_amount,0),
    48. if(old.payment_date_first is null and new.payment_count>0,'$do_date',old.payment_date_first),
    49. if(new.payment_count>0,'$do_date',old.payment_date_last),
    50. nvl(old.payment_count,0)+nvl(new.payment_count,0),
    51. nvl(old.payment_amount,0)+nvl(new.payment_amount,0),
    52. nvl(new.payment_last_30d_count,0),
    53. nvl(new.payment_last_30d_amount,0)
    54. from
    55. ${APP}.dwt_user_topic old
    56. full outer join
    57. (
    58. select
    59. user_id,
    60. sum(if(dt='$do_date',login_count,0)) login_count,
    61. sum(if(dt='$do_date',order_count,0)) order_count,
    62. sum(if(dt='$do_date',order_amount,0)) order_amount,
    63. sum(if(dt='$do_date',payment_count,0)) payment_count,
    64. sum(if(dt='$do_date',payment_amount,0)) payment_amount,
    65. sum(if(login_count>0,1,0)) login_last_30d_count,
    66. sum(order_count) order_last_30d_count,
    67. sum(order_amount) order_last_30d_amount,
    68. sum(payment_count) payment_last_30d_count,
    69. sum(payment_amount) payment_last_30d_amount
    70. from ${APP}.dws_user_action_daycount
    71. where dt>=date_add( '$do_date',-30)
    72. group by user_id
    73. )new
    74. on old.user_id=new.user_id;
    75. insert overwrite table ${APP}.dwt_sku_topic
    76. select
    77. nvl(new.sku_id,old.sku_id),
    78. sku_info.spu_id,
    79. nvl(new.order_count30,0),
    80. nvl(new.order_num30,0),
    81. nvl(new.order_amount30,0),
    82. nvl(old.order_count,0) + nvl(new.order_count,0),
    83. nvl(old.order_num,0) + nvl(new.order_num,0),
    84. nvl(old.order_amount,0) + nvl(new.order_amount,0),
    85. nvl(new.payment_count30,0),
    86. nvl(new.payment_num30,0),
    87. nvl(new.payment_amount30,0),
    88. nvl(old.payment_count,0) + nvl(new.payment_count,0),
    89. nvl(old.payment_num,0) + nvl(new.payment_count,0),
    90. nvl(old.payment_amount,0) + nvl(new.payment_count,0),
    91. nvl(new.refund_count30,0),
    92. nvl(new.refund_num30,0),
    93. nvl(new.refund_amount30,0),
    94. nvl(old.refund_count,0) + nvl(new.refund_count,0),
    95. nvl(old.refund_num,0) + nvl(new.refund_num,0),
    96. nvl(old.refund_amount,0) + nvl(new.refund_amount,0),
    97. nvl(new.cart_count30,0),
    98. nvl(old.cart_count,0) + nvl(new.cart_count,0),
    99. nvl(new.favor_count30,0),
    100. nvl(old.favor_count,0) + nvl(new.favor_count,0),
    101. nvl(new.appraise_good_count30,0),
    102. nvl(new.appraise_mid_count30,0),
    103. nvl(new.appraise_bad_count30,0),
    104. nvl(new.appraise_default_count30,0) ,
    105. nvl(old.appraise_good_count,0) + nvl(new.appraise_good_count,0),
    106. nvl(old.appraise_mid_count,0) + nvl(new.appraise_mid_count,0),
    107. nvl(old.appraise_bad_count,0) + nvl(new.appraise_bad_count,0),
    108. nvl(old.appraise_default_count,0) + nvl(new.appraise_default_count,0)
    109. from
    110. (
    111. select
    112. sku_id,
    113. spu_id,
    114. order_last_30d_count,
    115. order_last_30d_num,
    116. order_last_30d_amount,
    117. order_count,
    118. order_num,
    119. order_amount ,
    120. payment_last_30d_count,
    121. payment_last_30d_num,
    122. payment_last_30d_amount,
    123. payment_count,
    124. payment_num,
    125. payment_amount,
    126. refund_last_30d_count,
    127. refund_last_30d_num,
    128. refund_last_30d_amount,
    129. refund_count,
    130. refund_num,
    131. refund_amount,
    132. cart_last_30d_count,
    133. cart_count,
    134. favor_last_30d_count,
    135. favor_count,
    136. appraise_last_30d_good_count,
    137. appraise_last_30d_mid_count,
    138. appraise_last_30d_bad_count,
    139. appraise_last_30d_default_count,
    140. appraise_good_count,
    141. appraise_mid_count,
    142. appraise_bad_count,
    143. appraise_default_count
    144. from ${APP}.dwt_sku_topic
    145. )old
    146. full outer join
    147. (
    148. select
    149. sku_id,
    150. sum(if(dt='$do_date', order_count,0 )) order_count,
    151. sum(if(dt='$do_date',order_num ,0 )) order_num,
    152. sum(if(dt='$do_date',order_amount,0 )) order_amount ,
    153. sum(if(dt='$do_date',payment_count,0 )) payment_count,
    154. sum(if(dt='$do_date',payment_num,0 )) payment_num,
    155. sum(if(dt='$do_date',payment_amount,0 )) payment_amount,
    156. sum(if(dt='$do_date',refund_count,0 )) refund_count,
    157. sum(if(dt='$do_date',refund_num,0 )) refund_num,
    158. sum(if(dt='$do_date',refund_amount,0 )) refund_amount,
    159. sum(if(dt='$do_date',cart_count,0 )) cart_count,
    160. sum(if(dt='$do_date',favor_count,0 )) favor_count,
    161. sum(if(dt='$do_date',appraise_good_count,0 )) appraise_good_count,
    162. sum(if(dt='$do_date',appraise_mid_count,0 ) ) appraise_mid_count ,
    163. sum(if(dt='$do_date',appraise_bad_count,0 )) appraise_bad_count,
    164. sum(if(dt='$do_date',appraise_default_count,0 )) appraise_default_count,
    165. sum(order_count) order_count30 ,
    166. sum(order_num) order_num30,
    167. sum(order_amount) order_amount30,
    168. sum(payment_count) payment_count30,
    169. sum(payment_num) payment_num30,
    170. sum(payment_amount) payment_amount30,
    171. sum(refund_count) refund_count30,
    172. sum(refund_num) refund_num30,
    173. sum(refund_amount) refund_amount30,
    174. sum(cart_count) cart_count30,
    175. sum(favor_count) favor_count30,
    176. sum(appraise_good_count) appraise_good_count30,
    177. sum(appraise_mid_count) appraise_mid_count30,
    178. sum(appraise_bad_count) appraise_bad_count30,
    179. sum(appraise_default_count) appraise_default_count30
    180. from ${APP}.dws_sku_action_daycount
    181. where dt >= date_add ('$do_date', -30)
    182. group by sku_id
    183. )new
    184. on new.sku_id = old.sku_id
    185. left join
    186. (select * from ${APP}.dwd_dim_sku_info where dt='$do_date') sku_info
    187. on nvl(new.sku_id,old.sku_id)= sku_info.id;
    188. insert overwrite table ${APP}.dwt_activity_topic
    189. select
    190. nvl(new.id,old.id),
    191. nvl(new.activity_name,old.activity_name),
    192. nvl(new.activity_type,old.activity_type),
    193. nvl(new.start_time,old.start_time),
    194. nvl(new.end_time,old.end_time),
    195. nvl(new.create_time,old.create_time),
    196. nvl(new.display_count,0),
    197. nvl(new.order_count,0),
    198. nvl(new.order_amount,0.0),
    199. nvl(new.payment_count,0),
    200. nvl(new.payment_amount,0.0),
    201. nvl(new.display_count,0)+nvl(old.display_count,0),
    202. nvl(new.order_count,0)+nvl(old.order_count,0),
    203. nvl(new.order_amount,0.0)+nvl(old.order_amount,0.0),
    204. nvl(new.payment_count,0)+nvl(old.payment_count,0),
    205. nvl(new.payment_amount,0.0)+nvl(old.payment_amount,0.0)
    206. from
    207. (
    208. select
    209. *
    210. from ${APP}.dwt_activity_topic
    211. )old
    212. full outer join
    213. (
    214. select
    215. *
    216. from ${APP}.dws_activity_info_daycount
    217. where dt='$do_date'
    218. )new
    219. on old.id=new.id;
    220. insert overwrite table ${APP}.dwt_area_topic
    221. select
    222. nvl(old.id,new.id),
    223. nvl(old.province_name,new.province_name),
    224. nvl(old.area_code,new.area_code),
    225. nvl(old.iso_code,new.iso_code),
    226. nvl(old.region_id,new.region_id),
    227. nvl(old.region_name,new.region_name),
    228. nvl(new.login_day_count,0),
    229. nvl(new.login_last_30d_count,0),
    230. nvl(new.order_day_count,0),
    231. nvl(new.order_day_amount,0.0),
    232. nvl(new.order_last_30d_count,0),
    233. nvl(new.order_last_30d_amount,0.0),
    234. nvl(new.payment_day_count,0),
    235. nvl(new.payment_day_amount,0.0),
    236. nvl(new.payment_last_30d_count,0),
    237. nvl(new.payment_last_30d_amount,0.0)
    238. from
    239. (
    240. select
    241. *
    242. from ${APP}.dwt_area_topic
    243. )old
    244. full outer join
    245. (
    246. select
    247. id,
    248. province_name,
    249. area_code,
    250. iso_code,
    251. region_id,
    252. region_name,
    253. sum(if(dt='$do_date',login_count,0)) login_day_count,
    254. sum(if(dt='$do_date',order_count,0)) order_day_count,
    255. sum(if(dt='$do_date',order_amount,0.0)) order_day_amount,
    256. sum(if(dt='$do_date',payment_count,0)) payment_day_count,
    257. sum(if(dt='$do_date',payment_amount,0.0)) payment_day_amount,
    258. sum(login_count) login_last_30d_count,
    259. sum(order_count) order_last_30d_count,
    260. sum(order_amount) order_last_30d_amount,
    261. sum(payment_count) payment_last_30d_count,
    262. sum(payment_amount) payment_last_30d_amount
    263. from ${APP}.dws_area_stats_daycount
    264. where dt>=date_add('$do_date',-30)
    265. group by id,province_name,area_code,iso_code,region_id,region_name
    266. )new
    267. on old.id=new.id;
    268. "
    269. $hive -e "$sql"

    2)增加脚本执行权限

    [atguigu@hadoop102 bin]$ chmod 777 dws_to_dwt.sh

    3)执行脚本导入数据

    [atguigu@hadoop102 bin]$ dws_to_dwt.sh 2020-06-15

    4)查看导入数据

    hive (gmall)>
    select * from dwt_uv_topic limit 5;
    select * from dwt_user_topic limit 5;
    select * from dwt_sku_topic limit 5;
    select * from dwt_activity_topic limit 5;
    select * from dwt_area_topic limit 5;

    六十九.ADS_设备主体_活跃设备---这里的方案是很多的

    需求定义:
    日活:当日活跃的设备数
    周活:当周活跃的设备数
    月活:当月活跃的设备数

    1)建表语句

    1. drop table if exists ads_uv_count;
    2. create external table ads_uv_count(
    3. `dt` string COMMENT '统计日期',
    4. `day_count` bigint COMMENT '当日用户数量',
    5. `wk_count` bigint COMMENT '当周用户数量',
    6. `mn_count` bigint COMMENT '当月用户数量',
    7. `is_weekend` string COMMENT 'Y,N是否是周末,用于得到本周最终结果',
    8. `is_monthend` string COMMENT 'Y,N是否是月末,用于得到本月最终结果'
    9. ) COMMENT '活跃设备数'
    10. row format delimited fields terminated by '\t'
    11. location '/warehouse/gmall/ads/ads_uv_count/';

    2)导入数据

    1. insert into table ads_uv_count
    2. select
    3. '2020-06-14' dt,
    4. daycount.ct,
    5. wkcount.ct,
    6. mncount.ct,
    7. if(date_add(next_day('2020-06-14','MO'),-1)='2020-06-14','Y','N') ,
    8. if(last_day('2020-06-14')='2020-06-14','Y','N')
    9. from
    10. (
    11. select
    12. '2020-06-14' dt,
    13. count(*) ct
    14. from dwt_uv_topic
    15. where login_date_last='2020-06-14'
    16. )daycount join
    17. (
    18. select
    19. '2020-06-14' dt,
    20. count (*) ct
    21. from dwt_uv_topic
    22. where login_date_last>=date_add(next_day('2020-06-14','MO'),-7)
    23. and login_date_last<= date_add(next_day('2020-06-14','MO'),-1)
    24. ) wkcount on daycount.dt=wkcount.dt
    25. join
    26. (
    27. select
    28. '2020-06-14' dt,
    29. count (*) ct
    30. from dwt_uv_topic
    31. where date_format(login_date_last,'yyyy-MM')=date_format('2020-06-14','yyyy-MM')
    32. )mncount on daycount.dt=mncount.dt;

    下面的代码是老师上课讲的

    1. insert into table ads_uv_count
    2. select
    3. '2020-06-15'
    4. sum(if(login_date_last='2020-06-15',1,0)),
    5. sum(if(login_date_last>=date_add(next_day('2020-06-14','MO'),-7) and login_date_last <=date_add(next_day('2020-06-14','MO'),-1) )),
    6. sum(if(date_format(login_date_last,'yyyy-MM')=date_format('2020-06-15','yyyy-MM'),1,0)),
    7. if('2020-06-15'=date_add(next_day('2020-06-14','MO'),-7),'Y','N'),
    8. if('2020-06-15'=last_day('2020-06-14','Y','N'),
    9. from dwt_uv_topic;

    在ads层导入的数据是只有一天的,数据量是比较少的,只有一条数据,就没有必要进行压缩和列式存储了,我们在往mysql之中进行导入的时候,只能够进行全表导入。这个地方是不能够使用overwrite,因为没有进行相应的分区,如果要是使用了overwrite就会导致每天只有一张最新的表。因此,这里改成了insert into。

    七十.ADS_每日新增设备进行导入

    1)建表语句

    1. drop table if exists ads_new_mid_count;
    2. create external table ads_new_mid_count
    3. (
    4. `create_date` string comment '创建时间' ,
    5. `new_mid_count` BIGINT comment '新增设备数量'
    6. ) COMMENT '每日新增设备数量'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_new_mid_count/';

    2)导入数据

    1. insert into table ads_new_mid_count
    2. select
    3. '2020-06-14',
    4. count(*)
    5. from dwt_uv_topic
    6. where login_date_first='2020-06-14';

    七十一.ADS_沉默用户

    需求定义:
    沉默用户:只在安装当天启动过,且启动时间是在7天前

    1)建表语句

    1. drop table if exists ads_silent_count;
    2. create external table ads_silent_count(
    3. `dt` string COMMENT '统计日期',
    4. `silent_count` bigint COMMENT '沉默设备数'
    5. ) COMMENT '沉默用户数'
    6. row format delimited fields terminated by '\t'
    7. location '/warehouse/gmall/ads/ads_silent_count';

    2)导入2020-06-25数据

    1. insert into table ads_silent_count
    2. select
    3. '2020-06-25',
    4. count(*)
    5. from dwt_uv_topic
    6. where login_date_first=login_date_last
    7. and login_date_last<=date_add('2020-06-25',-7);

    七十二.多表join出现的问题_使用COALESCE函数解决

    1. full outer join b on a.id=b.id
    2. full outer join c on a.id=c.id
    3. full outer join d on a.id=d.id
    4. full outer join e on a.id=e.id

    上面的表在进行相应的join的时候,是存在一定的问题的使用nvl只能够判断二者之间,因此这里提出使用COALESCE函数进行解决。因此,这里的多表进行全外联的写法是如下所示:

    1. full outer join b on a.id=b.id
    2. full outer join c on nvl(a.id,b.id)=c.id
    3. full outer join d on coalesce(a.id,b.id,c.id)=d.id
    4. full outer join e on coalesce(a.id,b.id,c.id,d.id)=e.id

    (回宿舍去吃饭)

    七十三.ADS_设备主题_留存

    留存用户:某段时间内新增用户(活跃用户),经过一段时间后,又继续使用应用的被认作是留存用户 
    留存率:留存用户占当时新增用户(活跃用户的比例)就是留存率.

    在算取相应的留存率的时候:
    --- 2020-06-15 的 1 日 留存率
    --- 2020-06-15 的 新增
    --- 2020-06-16 的 活跃 ---- 2020-06-17得到

    --- 2020-06-15 的 2 日 留存率
    --- 2020-06-15 的 新增
    --- 2020-06-17 的 活跃 ---- 2020-06-18得到

    --- 2020-06-15 的 3 日 留存率
    --- 2020-06-15 的 新增
    --- 2020-06-18 的 活跃 ---- 2020-06-19得到

    --- 2020-06-19 的 计算任务是什么?
    --- 2020-06-15 的 3 日 留存率
    --- 2020-06-16 的 2 日 留存率
    --- 2020-06-17 的 1 日 留存率

    1)建表语句

    1. drop table if exists ads_user_retention_day_rate;
    2. create external table ads_user_retention_day_rate
    3. (
    4. `stat_date` string comment '统计日期',
    5. `create_date`       string comment '设备新增日期',
    6. `retention_day`     int comment '截止当前日期留存天数',
    7. `retention_count` bigint comment '留存数量',
    8. `new_mid_count`     bigint comment '设备新增数量',
    9. `retention_ratio`   decimal(16,2) comment '留存率'
    10. ) COMMENT '留存率'
    11. row format delimited fields terminated by '\t'
    12. location '/warehouse/gmall/ads/ads_user_retention_day_rate/';

    2)导入数据

    1. insert into table ads_user_retention_day_rate
    2. select
    3. '2020-06-15',
    4. date_add('2020-06-15',-1),
    5. 1,--留存天数
    6. sum(if(login_date_first=date_add('2020-06-15',-1) and login_date_last='2020-06-15',1,0)),
    7. sum(if(login_date_first=date_add('2020-06-15',-1),1,0)),
    8. sum(if(login_date_first=date_add('2020-06-15',-1) and login_date_last='2020-06-15',1,0))/sum(if(login_date_first=date_add('2020-06-15',-1),1,0))*100
    9. from dwt_uv_topic
    10. union all
    11. select
    12. '2020-06-15',
    13. date_add('2020-06-15',-2),
    14. 2,
    15. sum(if(login_date_first=date_add('2020-06-15',-2) and login_date_last='2020-06-15',1,0)),
    16. sum(if(login_date_first=date_add('2020-06-15',-2),1,0)),
    17. sum(if(login_date_first=date_add('2020-06-15',-2) and login_date_last='2020-06-15',1,0))/sum(if(login_date_first=date_add('2020-06-15',-2),1,0))*100
    18. from dwt_uv_topic
    19. union all
    20. select
    21. '2020-06-15',
    22. date_add('2020-06-15',-3),
    23. 3,
    24. sum(if(login_date_first=date_add('2020-06-15',-3) and login_date_last='2020-06-15',1,0)),
    25. sum(if(login_date_first=date_add('2020-06-15',-3),1,0)),
    26. sum(if(login_date_first=date_add('2020-06-15',-3) and login_date_last='2020-06-15',1,0))/sum(if(login_date_first=date_add('2020-06-15',-3),1,0))*100
    27. from dwt_uv_topic;

    3)查询导入数据

    hive (gmall)>select * from ads_user_retention_day_rate;

    七十四.ADS_设备主题_本周回流

    本周回流用户:上周未活跃,本周活跃的设备,且不是本周新增设备
    1)建表语句

    1. drop table if exists ads_back_count;
    2. create external table ads_back_count(
    3. `dt` string COMMENT '统计日期',
    4. `wk_dt` string COMMENT '统计日期所在周',
    5. `wastage_count` bigint COMMENT '回流设备数'
    6. ) COMMENT '本周回流用户数'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_back_count';

    2)导入数据
    首先拿到本周活跃的数据,
    第二件事是将本周新增的数据进行过滤---使用一个and操作,就是将第一天进行登陆的人进行直接的删除掉,
    第三件事取出上周活跃,使用join的操作,就是二者之间有重合的部分(本周活跃,上周没有活跃的部分),本周left join上周null

    1. select
    2. mid_id
    3. from dwt_uv_detail_daycount
    4. where dt>=date_add(next_day('2020-06-25','MO'),-7*2)
    5. and dt<= date_add(next_day('2020-06-25','MO'),-7-1)

    假如有一个设备上周活跃了,本周也活跃了,那么login_date_last是本周了,因此下面的这段代码实现上周活跃是不可以的,只能够使用相应的dws进行实验.

    1. insert into table ads_back_count
    2. select
    3. '2020-06-25',
    4. concat(date_add(next_day('2020-06-25','MO'),-7),'_', date_add(next_day('2020-06-25','MO'),-1)),
    5. count(*)
    6. from
    7. (
    8. select
    9. mid_id
    10. from dwt_uv_topic
    11. where login_date_last>=date_add(next_day('2020-06-25','MO'),-7)
    12. and login_date_last<= date_add(next_day('2020-06-25','MO'),-1)
    13. and login_date_first<date_add(next_day('2020-06-25','MO'),-7)
    14. )current_wk
    15. left join
    16. (
    17. select
    18. mid_id
    19. from dws_uv_detail_daycount
    20. where dt>=date_add(next_day('2020-06-25','MO'),-7*2)
    21. and dt<= date_add(next_day('2020-06-25','MO'),-7-1)
    22. group by mid_id -----进行相应的去重
    23. )last_wk
    24. on current_wk.mid_id=last_wk.mid_id
    25. where last_wk.mid_id is null;

    知道如上的代码可以得到相应的上周为null的代码.

    3)查询结果

    hive (gmall)> select * from ads_back_count;

    七十五.ADS_设备主题_流失用户数

    流失用户:最近7天未活跃的设备-------最后一次活跃在七天前

    1)建表语句

    1. drop table if exists ads_wastage_count;
    2. create external table ads_wastage_count(
    3. `dt` string COMMENT '统计日期',
    4. `wastage_count` bigint COMMENT '流失设备数'
    5. ) COMMENT '流失用户数'
    6. row format delimited fields terminated by '\t'
    7. location '/warehouse/gmall/ads/ads_wastage_count';

    2)导入2020-06-25数据

    1. insert into table ads_wastage_count
    2. select
    3. '2020-06-25',
    4. count(*)
    5. from
    6. (
    7. select
    8. mid_id
    9. from dwt_uv_topic
    10. where login_date_last<=date_add('2020-06-25',-7)
    11. group by mid_id
    12. )t1;

    3)查询结果

    hive (gmall)> select * from ads_wastage_count;

    七十六.Hiveserver2_heap_size

    出现java.lang.OutOfMemoryError的问题.
    需要进到hive/conf目录下面,在这个目录的下方有一个hive-env.sh.template
    $ mv hive-env.sh.template hive-env.sh --- 使得这个脚本生效

    去重使用union,不去重就用union all,多个表使用union进行连接,就当成是一个select就可以的.

    (回宿舍恰觉)


    真的无语了,宿舍有阳性了,封在宿舍已经四天了,什么也没有干,玩了四天,好愧疚.

    七十七.ADS_设备主题_最近三周连续活跃

    1.建表语句

    1. drop table if exists ads_continuity_wk_count;
    2. create external table ads_continuity_wk_count(
    3. `dt` string COMMENT '统计日期,一般用结束周周日日期,如果每天计算一次,可用当天日期',
    4. `wk_dt` string COMMENT '持续时间',
    5. `continuity_count` bigint COMMENT '活跃次数'
    6. ) COMMENT '最近连续三周活跃用户数'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_continuity_wk_count';

    2.导入数据

    注意下面的连接方法是使用的union all的方式进行连接.最后的判断是使用having进行条件截取,where是过滤的一行一样的数据,having进行过滤的是分完组之后的组.

    1. insert into table ads_continuity_wk_count
    2. select
    3. '2020-06-25',
    4. concat(date_add(next_day('2020-06-25','MO'),-7*3),'_',date_add(next_day('2020-06-25','MO'),-1)),
    5. count(*)
    6. from
    7. (
    8. select
    9. mid_id
    10. from
    11. (
    12. select
    13. mid_id
    14. from dws_uv_detail_daycount
    15. where dt>=date_add(next_day('2020-06-25','monday'),-7)
    16. and dt<=date_add(next_day('2020-06-25','monday'),-1)
    17. group by mid_id
    18. union all
    19. select
    20. mid_id
    21. from dws_uv_detail_daycount
    22. where dt>=date_add(next_day('2020-06-25','monday'),-7*2)
    23. and dt<=date_add(next_day('2020-06-25','monday'),-7-1)
    24. group by mid_id
    25. union all
    26. select
    27. mid_id
    28. from dws_uv_detail_daycount
    29. where dt>=date_add(next_day('2020-06-25','monday'),-7*3)
    30. and dt<=date_add(next_day('2020-06-25','monday'),-7*2-1)
    31. group by mid_id
    32. )t1
    33. group by mid_id
    34. having count(*)=3
    35. )t2;

    七十八.ADS_设备主题_最近七天连续三天的活跃次数

    1.建表语句

    1. drop table if exists ads_continuity_uv_count;
    2. create external table ads_continuity_uv_count(
    3. `dt` string COMMENT '统计日期',
    4. `wk_dt` string COMMENT '最近7天日期',
    5. `continuity_count` bigint
    6. ) COMMENT '最近七天内连续三天活跃用户数'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_continuity_uv_count';

    2.导入数据

    下面应当注意的是写的思路.

    特别注意上面的rank()函数的使用

    1. insert into table ads_continuity_uv_count
    2. select
    3. '2020-06-16',
    4. concat(date_add('2020-06-16',-6),'_','2020-06-16'),
    5. count(*)
    6. from
    7. (
    8. select mid_id
    9. from
    10. (
    11. select mid_id
    12. from
    13. (
    14. select
    15. mid_id,
    16. date_sub(dt,rank) date_dif
    17. from
    18. (
    19. select
    20. mid_id,
    21. dt,
    22. rank() over(partition by mid_id order by dt) rank--进行一个开窗处理
    23. from dws_uv_detail_daycount
    24. where dt>=date_add('2020-06-16',-6) and dt<='2020-06-16'
    25. )t1
    26. )t2
    27. group by mid_id,date_dif
    28. having count(*)>=3
    29. )t3
    30. group by mid_id
    31. )t4;

    第二种思路:使用下面两行进行相减的过程.

     只要能够找到一个差值为2的数据,就是说明是正常的.

    七十九.ADS_会员主题信息表

    1.建表语句

    1. drop table if exists ads_user_topic;
    2. create external table ads_user_topic(
    3. `dt` string COMMENT '统计日期',
    4. `day_users` string COMMENT '活跃会员数',
    5. `day_new_users` string COMMENT '新增会员数',
    6. `day_new_payment_users` string COMMENT '新增消费会员数',
    7. `payment_users` string COMMENT '总付费会员数',
    8. `users` string COMMENT '总会员数',
    9. `day_users2users` decimal(16,2) COMMENT '会员活跃率',
    10. `payment_users2users` decimal(16,2) COMMENT '会员付费率',
    11. `day_new_users2users` decimal(16,2) COMMENT '会员新鲜度'
    12. ) COMMENT '会员信息表'
    13. row format delimited fields terminated by '\t'
    14. location '/warehouse/gmall/ads/ads_user_topic';

    会员新鲜度是指当日的新增会员除以活跃会员数目.

    2.导入数据

    1. insert into table ads_user_topic
    2. select
    3. '2020-06-14',
    4. sum(if(login_date_last='2020-06-14',1,0)),
    5. sum(if(login_date_first='2020-06-14',1,0)),
    6. sum(if(payment_date_first='2020-06-14',1,0)),
    7. sum(if(payment_count>0,1,0)),
    8. count(*),
    9. sum(if(login_date_last='2020-06-14',1,0))/count(*),
    10. sum(if(payment_count>0,1,0))/count(*),
    11. sum(if(login_date_first='2020-06-14',1,0))/sum(if(login_date_last='2020-06-14',1,0))
    12. from dwt_user_topic;

    八十.ADS_漏斗分析

    统计“浏览首页->浏览商品详情页->加入购物车->下单->支付”的转化率

    思路:统计各个行为的人数,然后计算比值。

    1.建表语句

    1. drop table if exists ads_user_action_convert_day;
    2. create external table ads_user_action_convert_day(
    3. `dt` string COMMENT '统计日期',
    4. `home_count` bigint COMMENT '浏览首页人数',
    5. `good_detail_count` bigint COMMENT '浏览商品详情页人数',
    6. `home2good_detail_convert_ratio` decimal(16,2) COMMENT '首页到商品详情转化率',
    7. `cart_count` bigint COMMENT '加入购物车的人数',
    8. `good_detail2cart_convert_ratio` decimal(16,2) COMMENT '商品详情页到加入购物车转化率',
    9. `order_count` bigint COMMENT '下单人数',
    10. `cart2order_convert_ratio` decimal(16,2) COMMENT '加入购物车到下单转化率',
    11. `payment_amount` bigint COMMENT '支付人数',
    12. `order2payment_convert_ratio` decimal(16,2) COMMENT '下单到支付的转化率'
    13. ) COMMENT '漏斗分析'
    14. row format delimited fields terminated by '\t'
    15. location '/warehouse/gmall/ads/ads_user_action_convert_day/';

    浏览首页和浏览商品详情页是使用相应的设备id进行统计.这里的加入购物车有的是需要登陆的,有的是不需要登陆的.

    2.导入数据

    平时使用union更加好一些,要是使用join它的效率是比较低的.

    1. with
    2. tmp_uv as
    3. (
    4. select
    5. '2020-06-14' dt,
    6. sum(if(array_contains(pages,'home'),1,0)) home_count,---使用了一个数组,并且进行判断相应的信息是否在这个里面
    7. sum(if(array_contains(pages,'good_detail'),1,0)) good_detail_count
    8. from
    9. (
    10. select
    11. mid_id,
    12. collect_set(page_id) pages---聚合函数,进行一个分组
    13. from dwd_page_log
    14. where dt='2020-06-14'
    15. and page_id in ('home','good_detail')---首页和商品详情页面
    16. group by mid_id
    17. )tmp
    18. ),
    19. tmp_cop as
    20. (
    21. select
    22. '2020-06-14' dt,
    23. sum(if(cart_count>0,1,0)) cart_count,
    24. sum(if(order_count>0,1,0)) order_count,
    25. sum(if(payment_count>0,1,0)) payment_count
    26. from dws_user_action_daycount
    27. where dt='2020-06-14'
    28. )
    29. insert into table ads_user_action_convert_day
    30. select
    31. tmp_uv.dt,
    32. tmp_uv.home_count,
    33. tmp_uv.good_detail_count,
    34. tmp_uv.good_detail_count/tmp_uv.home_count*100,
    35. tmp_cop.cart_count,
    36. tmp_cop.cart_count/tmp_uv.good_detail_count*100,
    37. tmp_cop.order_count,
    38. tmp_cop.order_count/tmp_cop.cart_count*100,
    39. tmp_cop.payment_count,
    40. tmp_cop.payment_count/tmp_cop.order_count*100
    41. from tmp_uv
    42. join tmp_cop
    43. on tmp_uv.dt=tmp_cop.dt;

    八十一.ADS_商品主题_商品个数

    1.建表语句

    1. drop table if exists ads_product_info;
    2. create external table ads_product_info(
    3. `dt` string COMMENT '统计日期',
    4. `sku_num` string COMMENT 'sku个数',
    5. `spu_num` string COMMENT 'spu个数'
    6. ) COMMENT '商品个数信息'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_product_info';

    2.代入数据------实际操作之中是要进行避免使用distinct的

    1. insert into table ads_product_info
    2. select
    3. '2020-06-14' dt,
    4. sku_num,
    5. spu_num
    6. from
    7. (
    8. select
    9. '2020-06-14' dt,
    10. count(*) sku_num
    11. from
    12. dwt_sku_topic
    13. ) tmp_sku_num
    14. join
    15. (
    16. select
    17. '2020-06-14' dt,
    18. count(*) spu_num
    19. from
    20. (
    21. select
    22. spu_id
    23. from
    24. dwt_sku_topic
    25. group by
    26. spu_id
    27. ) tmp_spu_id
    28. ) tmp_spu_num
    29. on tmp_sku_num.dt=tmp_spu_num.dt;

    八十二.ADS_商品主题_全局TopN

    A.销量排名

    1.建表语句

    1. drop table if exists ads_product_sale_topN;
    2. create external table ads_product_sale_topN(
    3. `dt` string COMMENT '统计日期',
    4. `sku_id` string COMMENT '商品ID',
    5. `payment_amount` bigint COMMENT '销量'
    6. ) COMMENT '商品销量排名'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_product_sale_topN';

    2.导入数据

    1. insert into table ads_product_sale_topN
    2. select
    3. '2020-06-14' dt,
    4. sku_id,
    5. payment_amount
    6. from
    7. dws_sku_action_daycount
    8. where
    9. dt='2020-06-14'
    10. order by payment_amount desc
    11. limit 10;

    B.收藏排名

    1.建表语句

    1. drop table if exists ads_product_favor_topN;
    2. create external table ads_product_favor_topN(
    3. `dt` string COMMENT '统计日期',
    4. `sku_id` string COMMENT '商品ID',
    5. `favor_count` bigint COMMENT '收藏量'
    6. ) COMMENT '商品收藏排名'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_product_favor_topN';

    2.导入数据

    1. insert into table ads_product_favor_topN
    2. select
    3. '2020-06-14' dt,
    4. sku_id,
    5. favor_count
    6. from
    7. dws_sku_action_daycount
    8. where
    9. dt='2020-06-14'
    10. order by favor_count desc
    11. limit 10;

    C.购物排名

    1.建表语句

    1. drop table if exists ads_product_cart_topN;
    2. create external table ads_product_cart_topN(
    3. `dt` string COMMENT '统计日期',
    4. `sku_id` string COMMENT '商品ID',
    5. `cart_count` bigint COMMENT '加入购物车次数'
    6. ) COMMENT '商品加入购物车排名'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_product_cart_topN';

    2.导入数据

    1. insert into table ads_product_cart_topN
    2. select
    3. '2020-06-14' dt,
    4. sku_id,
    5. cart_count
    6. from
    7. dws_sku_action_daycount
    8. where
    9. dt='2020-06-14'
    10. order by cart_count desc
    11. limit 10;

    八十三.ADS_商品主题_退款率

    1.建表语句

    1. drop table if exists ads_product_refund_topN;
    2. create external table ads_product_refund_topN(
    3. `dt` string COMMENT '统计日期',
    4. `sku_id` string COMMENT '商品ID',
    5. `refund_ratio` decimal(16,2) COMMENT '退款率'
    6. ) COMMENT '商品退款率排名'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_product_refund_topN';

    2.导入数据

    1. insert into table ads_product_refund_topN
    2. select
    3. '2020-06-14',
    4. sku_id,
    5. refund_last_30d_count/payment_last_30d_count*100 refund_ratio
    6. from dwt_sku_topic
    7. order by refund_ratio desc
    8. limit 10;

    八十四.ADS_商品主题_商品差评率

    1.建表语句

    1. drop table if exists ads_appraise_bad_topN;
    2. create external table ads_appraise_bad_topN(
    3. `dt` string COMMENT '统计日期',
    4. `sku_id` string COMMENT '商品ID',
    5. `appraise_bad_ratio` decimal(16,2) COMMENT '差评率'
    6. ) COMMENT '商品差评率'
    7. row format delimited fields terminated by '\t'
    8. location '/warehouse/gmall/ads/ads_appraise_bad_topN';

    2.导入数据

    1. insert into table ads_appraise_bad_topN
    2. select
    3. '2020-06-14' dt,
    4. sku_id,
    5. appraise_bad_count/(appraise_good_count+appraise_mid_count+appraise_bad_count+appraise_default_count) appraise_bad_ratio
    6. from
    7. dws_sku_action_daycount
    8. where
    9. dt='2020-06-14'
    10. order by appraise_bad_ratio desc
    11. limit 10;

    八十五.ADS_营销主题_下单支付统计

    需求分析:统计每日下单数,下单金额及下单用户数。

    1.建表语句

    1. drop table if exists ads_order_daycount;
    2. create external table ads_order_daycount(
    3. dt string comment '统计日期',
    4. order_count bigint comment '单日下单笔数',
    5. order_amount bigint comment '单日下单金额',
    6. order_users bigint comment '单日下单用户数'
    7. ) comment '下单数目统计'
    8. row format delimited fields terminated by '\t'
    9. location '/warehouse/gmall/ads/ads_order_daycount';

    2.导入数据

    1. insert into table ads_order_daycount
    2. select
    3. '2020-06-14',
    4. sum(order_count),
    5. sum(order_amount),
    6. sum(if(order_count>0,1,0))
    7. from dws_user_action_daycount
    8. where dt='2020-06-14';

    GMV这个概念的含义是包含付款的金额,也包含没有付款的金额.

    八十六.ADS_营销主题_支付信息统计

    每日支付金额、支付人数、支付商品数、支付笔数以及下单到支付的平均时长(取自DWD)

    1.建表

    1. drop table if exists ads_payment_daycount;
    2. create external table ads_payment_daycount(
    3. dt string comment '统计日期',
    4. order_count bigint comment '单日支付笔数',
    5. order_amount bigint comment '单日支付金额',--今天卖出多少商品,今天一共多少种商品卖出
    6. payment_user_count bigint comment '单日支付人数',
    7. payment_sku_count bigint comment '单日支付商品数',
    8. payment_avg_time decimal(16,2) comment '下单到支付的平均时长,取分钟数'
    9. ) comment '支付信息统计'
    10. row format delimited fields terminated by '\t'
    11. location '/warehouse/gmall/ads/ads_payment_daycount';

    2.导入数据

    1. insert into table ads_payment_daycount
    2. select
    3. tmp_payment.dt,
    4. tmp_payment.payment_count,
    5. tmp_payment.payment_amount,
    6. tmp_payment.payment_user_count,
    7. tmp_skucount.payment_sku_count,
    8. tmp_time.payment_avg_time
    9. from
    10. (
    11. select
    12. '2020-06-14' dt,
    13. sum(payment_count) payment_count,
    14. sum(payment_amount) payment_amount,
    15. sum(if(payment_count>0,1,0)) payment_user_count
    16. from dws_user_action_daycount
    17. where dt='2020-06-14'
    18. )tmp_payment
    19. join
    20. (
    21. select
    22. '2020-06-14' dt,
    23. sum(if(payment_count>0,1,0)) payment_sku_count
    24. from dws_sku_action_daycount
    25. where dt='2020-06-14'
    26. )tmp_skucount on tmp_payment.dt=tmp_skucount.dt
    27. join
    28. (
    29. select
    30. '2020-06-14' dt,
    31. sum(unix_timestamp(payment_time)-unix_timestamp(create_time))/count(*)/60
    32. --支付时间减去下单时间
    33. payment_avg_time
    34. from dwd_fact_order_info
    35. where dt='2020-06-14'
    36. and payment_time is not null
    37. )tmp_time on tmp_payment.dt=tmp_time.dt;

    八十七.ADS_商品主题_品牌复购率

    这里将买过一次的看作是购买的,买过两次的以及以上的视为是复购的,买过三次以上的看作为多次复购率.

    1.建表语句

    1. drop table ads_sale_tm_category1_stat_mn;
    2. create external table ads_sale_tm_category1_stat_mn
    3. (
    4. tm_id string comment '品牌id',
    5. category1_id string comment '1级品类id ',
    6. category1_name string comment '1级品类名称 ',
    7. buycount bigint comment '购买人数',
    8. buy_twice_last bigint comment '两次以上购买人数',
    9. buy_twice_last_ratio decimal(16,2) comment '单次复购率',
    10. buy_3times_last bigint comment '三次以上购买人数',
    11. buy_3times_last_ratio decimal(16,2) comment '多次复购率',
    12. stat_mn string comment '统计月份',
    13. stat_date string comment '统计日期'
    14. ) COMMENT '品牌复购率统计'
    15. row format delimited fields terminated by '\t'
    16. location '/warehouse/gmall/ads/ads_sale_tm_category1_stat_mn/';

    2.导入数据

    1. with
    2. tmp_order as
    3. (
    4. select
    5. user_id,
    6. order_stats_struct.sku_id sku_id,
    7. order_stats_struct.order_count order_count
    8. from dws_user_action_daycount lateral view explode(order_detail_stats) tmp as order_stats_struct
    9. where date_format(dt,'yyyy-MM')=date_format('2020-06-14','yyyy-MM')
    10. ),
    11. tmp_sku as
    12. (
    13. select
    14. id,
    15. tm_id,
    16. category1_id,
    17. category1_name
    18. from dwd_dim_sku_info
    19. where dt='2020-06-14'
    20. )
    21. insert into table ads_sale_tm_category1_stat_mn
    22. select
    23. tm_id,
    24. category1_id,
    25. category1_name,
    26. sum(if(order_count>=1,1,0)) buycount,
    27. sum(if(order_count>=2,1,0)) buyTwiceLast,
    28. sum(if(order_count>=2,1,0))/sum( if(order_count>=1,1,0)) buyTwiceLastRatio,
    29. sum(if(order_count>=3,1,0)) buy3timeLast ,
    30. sum(if(order_count>=3,1,0))/sum( if(order_count>=1,1,0)) buy3timeLastRatio ,
    31. date_format('2020-06-14' ,'yyyy-MM') stat_mn,
    32. '2020-06-14' stat_date
    33. from
    34. (
    35. select
    36. tmp_order.user_id,
    37. tmp_sku.category1_id,
    38. tmp_sku.category1_name,
    39. tmp_sku.tm_id,
    40. sum(order_count) order_count
    41. from tmp_order
    42. join tmp_sku
    43. on tmp_order.sku_id=tmp_sku.id
    44. group by tmp_order.user_id,tmp_sku.category1_id,tmp_sku.category1_name,tmp_sku.tm_id
    45. )tmp
    46. group by tm_id, category1_id, category1_name;

    八十八.ADS_地区建表语句

    1.建表

    1. drop table if exists ads_area_topic;
    2. create external table ads_area_topic(
    3. `dt` string COMMENT '统计日期',
    4. `id` bigint COMMENT '编号',
    5. `province_name` string COMMENT '省份名称',
    6. `area_code` string COMMENT '地区编码',
    7. `iso_code` string COMMENT 'iso编码',
    8. `region_id` string COMMENT '地区ID',
    9. `region_name` string COMMENT '地区名称',
    10. `login_day_count` bigint COMMENT '当天活跃设备数',
    11. `order_day_count` bigint COMMENT '当天下单次数',
    12. `order_day_amount` decimal(16,2) COMMENT '当天下单金额',
    13. `payment_day_count` bigint COMMENT '当天支付次数',
    14. `payment_day_amount` decimal(16,2) COMMENT '当天支付金额'
    15. ) COMMENT '地区主题信息'
    16. row format delimited fields terminated by '\t'
    17. location '/warehouse/gmall/ads/ads_area_topic/';

    2.数据装载

    1. insert into table ads_area_topic
    2. select
    3. '2020-06-14',
    4. id,
    5. province_name,
    6. area_code,
    7. iso_code,
    8. region_id,
    9. region_name,
    10. login_day_count,
    11. order_day_count,
    12. order_day_amount,
    13. payment_day_count,
    14. payment_day_amount
    15. from dwt_area_topic;

    八十九.ADS_脚本的建立

    1)在/home/atguigu/bin目录下创建脚本dwt_to_ads.sh

    [atguigu@hadoop102 bin]$ vim dwt_to_ads.sh

    在脚本中填写如下内容

    1. #!/bin/bash
    2. hive=/opt/module/hive/bin/hive
    3. APP=gmall
    4. # 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
    5. if [ -n "$1" ] ;then
    6. do_date=$1
    7. else
    8. do_date=`date -d "-1 day" +%F`
    9. fi
    10. sql="
    11. set mapreduce.job.queuename=hive;
    12. insert into table ${APP}.ads_uv_count
    13. select
    14. '$do_date' dt,
    15. daycount.ct,
    16. wkcount.ct,
    17. mncount.ct,
    18. if(date_add(next_day('$do_date','MO'),-1)='$do_date','Y','N') ,
    19. if(last_day('$do_date')='$do_date','Y','N')
    20. from
    21. (
    22. select
    23. '$do_date' dt,
    24. count(*) ct
    25. from ${APP}.dwt_uv_topic
    26. where login_date_last='$do_date'
    27. )daycount join
    28. (
    29. select
    30. '$do_date' dt,
    31. count (*) ct
    32. from ${APP}.dwt_uv_topic
    33. where login_date_last>=date_add(next_day('$do_date','MO'),-7)
    34. and login_date_last<= date_add(next_day('$do_date','MO'),-1)
    35. ) wkcount on daycount.dt=wkcount.dt
    36. join
    37. (
    38. select
    39. '$do_date' dt,
    40. count (*) ct
    41. from ${APP}.dwt_uv_topic
    42. where date_format(login_date_last,'yyyy-MM')=date_format('$do_date','yyyy-MM')
    43. )mncount on daycount.dt=mncount.dt;
    44. insert into table ${APP}.ads_new_mid_count
    45. select
    46. login_date_first,
    47. count(*)
    48. from ${APP}.dwt_uv_topic
    49. where login_date_first='$do_date'
    50. group by login_date_first;
    51. insert into table ${APP}.ads_silent_count
    52. select
    53. '$do_date',
    54. count(*)
    55. from ${APP}.dwt_uv_topic
    56. where login_date_first=login_date_last
    57. and login_date_last<=date_add('$do_date',-7);
    58. insert into table ${APP}.ads_back_count
    59. select
    60. '$do_date',
    61. concat(date_add(next_day('$do_date','MO'),-7),'_', date_add(next_day('$do_date','MO'),-1)),
    62. count(*)
    63. from
    64. (
    65. select
    66. mid_id
    67. from ${APP}.dwt_uv_topic
    68. where login_date_last>=date_add(next_day('$do_date','MO'),-7)
    69. and login_date_last<= date_add(next_day('$do_date','MO'),-1)
    70. and login_date_first$do_date','MO'),-7)
    71. )current_wk
    72. left join
    73. (
    74. select
    75. mid_id
    76. from ${APP}.dws_uv_detail_daycount
    77. where dt>=date_add(next_day('$do_date','MO'),-7*2)
    78. and dt<= date_add(next_day('$do_date','MO'),-7-1)
    79. group by mid_id
    80. )last_wk
    81. on current_wk.mid_id=last_wk.mid_id
    82. where last_wk.mid_id is null;
    83. insert into table ${APP}.ads_wastage_count
    84. select
    85. '$do_date',
    86. count(*)
    87. from
    88. (
    89. select
    90. mid_id
    91. from ${APP}.dwt_uv_topic
    92. where login_date_last<=date_add('$do_date',-7)
    93. group by mid_id
    94. )t1;
    95. insert into table ${APP}.ads_user_retention_day_rate
    96. select
    97. '$do_date',--统计日期
    98. date_add('$do_date',-1),--新增日期
    99. 1,--留存天数
    100. sum(if(login_date_first=date_add('$do_date',-1) and login_date_last='$do_date',1,0)),--$do_date的1日留存数
    101. sum(if(login_date_first=date_add('$do_date',-1),1,0)),--$do_date新增
    102. sum(if(login_date_first=date_add('$do_date',-1) and login_date_last='$do_date',1,0))/sum(if(login_date_first=date_add('$do_date',-1),1,0))*100
    103. from ${APP}.dwt_uv_topic
    104. union all
    105. select
    106. '$do_date',--统计日期
    107. date_add('$do_date',-2),--新增日期
    108. 2,--留存天数
    109. sum(if(login_date_first=date_add('$do_date',-2) and login_date_last='$do_date',1,0)),--$do_date的2日留存数
    110. sum(if(login_date_first=date_add('$do_date',-2),1,0)),--$do_date新增
    111. sum(if(login_date_first=date_add('$do_date',-2) and login_date_last='$do_date',1,0))/sum(if(login_date_first=date_add('$do_date',-2),1,0))*100
    112. from ${APP}.dwt_uv_topic
    113. union all
    114. select
    115. '$do_date',--统计日期
    116. date_add('$do_date',-3),--新增日期
    117. 3,--留存天数
    118. sum(if(login_date_first=date_add('$do_date',-3) and login_date_last='$do_date',1,0)),--$do_date的3日留存数
    119. sum(if(login_date_first=date_add('$do_date',-3),1,0)),--$do_date新增
    120. sum(if(login_date_first=date_add('$do_date',-3) and login_date_last='$do_date',1,0))/sum(if(login_date_first=date_add('$do_date',-3),1,0))*100
    121. from ${APP}.dwt_uv_topic;
    122. insert into table ${APP}.ads_continuity_wk_count
    123. select
    124. '$do_date',
    125. concat(date_add(next_day('$do_date','MO'),-7*3),'_',date_add(next_day('$do_date','MO'),-1)),
    126. count(*)
    127. from
    128. (
    129. select
    130. mid_id
    131. from
    132. (
    133. select
    134. mid_id
    135. from ${APP}.dws_uv_detail_daycount
    136. where dt>=date_add(next_day('$do_date','monday'),-7)
    137. and dt<=date_add(next_day('$do_date','monday'),-1)
    138. group by mid_id
    139. union all
    140. select
    141. mid_id
    142. from ${APP}.dws_uv_detail_daycount
    143. where dt>=date_add(next_day('$do_date','monday'),-7*2)
    144. and dt<=date_add(next_day('$do_date','monday'),-7-1)
    145. group by mid_id
    146. union all
    147. select
    148. mid_id
    149. from ${APP}.dws_uv_detail_daycount
    150. where dt>=date_add(next_day('$do_date','monday'),-7*3)
    151. and dt<=date_add(next_day('$do_date','monday'),-7*2-1)
    152. group by mid_id
    153. )t1
    154. group by mid_id
    155. having count(*)=3
    156. )t2;
    157. insert into table ${APP}.ads_continuity_uv_count
    158. select
    159. '$do_date',
    160. concat(date_add('$do_date',-6),'_','$do_date'),
    161. count(*)
    162. from
    163. (
    164. select mid_id
    165. from
    166. (
    167. select mid_id
    168. from
    169. (
    170. select
    171. mid_id,
    172. date_sub(dt,rank) date_dif
    173. from
    174. (
    175. select
    176. mid_id,
    177. dt,
    178. rank() over(partition by mid_id order by dt) rank
    179. from ${APP}.dws_uv_detail_daycount
    180. where dt>=date_add('$do_date',-6) and dt<='$do_date'
    181. )t1
    182. )t2
    183. group by mid_id,date_dif
    184. having count(*)>=3
    185. )t3
    186. group by mid_id
    187. )t4;
    188. insert into table ${APP}.ads_user_topic
    189. select
    190. '$do_date',
    191. sum(if(login_date_last='$do_date',1,0)),
    192. sum(if(login_date_first='$do_date',1,0)),
    193. sum(if(payment_date_first='$do_date',1,0)),
    194. sum(if(payment_count>0,1,0)),
    195. count(*),
    196. sum(if(login_date_last='$do_date',1,0))/count(*),
    197. sum(if(payment_count>0,1,0))/count(*),
    198. sum(if(login_date_first='$do_date',1,0))/sum(if(login_date_last='$do_date',1,0))
    199. from ${APP}.dwt_user_topic;
    200. with
    201. tmp_uv as
    202. (
    203. select
    204. '$do_date' dt,
    205. sum(if(array_contains(pages,'home'),1,0)) home_count,
    206. sum(if(array_contains(pages,'good_detail'),1,0)) good_detail_count
    207. from
    208. (
    209. select
    210. mid_id,
    211. collect_set(page_id) pages
    212. from ${APP}.dwd_page_log
    213. where dt='$do_date'
    214. and page_id in ('home','good_detail')
    215. group by mid_id
    216. )tmp
    217. ),
    218. tmp_cop as
    219. (
    220. select
    221. '$do_date' dt,
    222. sum(if(cart_count>0,1,0)) cart_count,
    223. sum(if(order_count>0,1,0)) order_count,
    224. sum(if(payment_count>0,1,0)) payment_count
    225. from ${APP}.dws_user_action_daycount
    226. where dt='$do_date'
    227. )
    228. insert into table ${APP}.ads_user_action_convert_day
    229. select
    230. tmp_uv.dt,
    231. tmp_uv.home_count,
    232. tmp_uv.good_detail_count,
    233. tmp_uv.good_detail_count/tmp_uv.home_count*100,
    234. tmp_cop.cart_count,
    235. tmp_cop.cart_count/tmp_uv.good_detail_count*100,
    236. tmp_cop.order_count,
    237. tmp_cop.order_count/tmp_cop.cart_count*100,
    238. tmp_cop.payment_count,
    239. tmp_cop.payment_count/tmp_cop.order_count*100
    240. from tmp_uv
    241. join tmp_cop
    242. on tmp_uv.dt=tmp_cop.dt;
    243. insert into table ${APP}.ads_product_info
    244. select
    245. '$do_date' dt,
    246. sku_num,
    247. spu_num
    248. from
    249. (
    250. select
    251. '$do_date' dt,
    252. count(*) sku_num
    253. from
    254. ${APP}.dwt_sku_topic
    255. ) tmp_sku_num
    256. join
    257. (
    258. select
    259. '$do_date' dt,
    260. count(*) spu_num
    261. from
    262. (
    263. select
    264. spu_id
    265. from
    266. ${APP}.dwt_sku_topic
    267. group by
    268. spu_id
    269. ) tmp_spu_id
    270. ) tmp_spu_num
    271. on
    272. tmp_sku_num.dt=tmp_spu_num.dt;
    273. insert into table ${APP}.ads_product_sale_topN
    274. select
    275. '$do_date' dt,
    276. sku_id,
    277. payment_amount
    278. from
    279. ${APP}.dws_sku_action_daycount
    280. where
    281. dt='$do_date'
    282. order by payment_amount desc
    283. limit 10;
    284. insert into table ${APP}.ads_product_favor_topN
    285. select
    286. '$do_date' dt,
    287. sku_id,
    288. favor_count
    289. from
    290. ${APP}.dws_sku_action_daycount
    291. where
    292. dt='$do_date'
    293. order by favor_count desc
    294. limit 10;
    295. insert into table ${APP}.ads_product_cart_topN
    296. select
    297. '$do_date' dt,
    298. sku_id,
    299. cart_count
    300. from
    301. ${APP}.dws_sku_action_daycount
    302. where
    303. dt='$do_date'
    304. order by cart_count desc
    305. limit 10;
    306. insert into table ${APP}.ads_product_refund_topN
    307. select
    308. '$do_date',
    309. sku_id,
    310. refund_last_30d_count/payment_last_30d_count*100 refund_ratio
    311. from ${APP}.dwt_sku_topic
    312. order by refund_ratio desc
    313. limit 10;
    314. insert into table ${APP}.ads_appraise_bad_topN
    315. select
    316. '$do_date' dt,
    317. sku_id,
    318. appraise_bad_count/(appraise_good_count+appraise_mid_count+appraise_bad_count+appraise_default_count) appraise_bad_ratio
    319. from
    320. ${APP}.dws_sku_action_daycount
    321. where
    322. dt='$do_date'
    323. order by appraise_bad_ratio desc
    324. limit 10;
    325. insert into table ${APP}.ads_order_daycount
    326. select
    327. '$do_date',
    328. sum(order_count),
    329. sum(order_amount),
    330. sum(if(order_count>0,1,0))
    331. from ${APP}.dws_user_action_daycount
    332. where dt='$do_date';
    333. insert into table ${APP}.ads_payment_daycount
    334. select
    335. tmp_payment.dt,
    336. tmp_payment.payment_count,
    337. tmp_payment.payment_amount,
    338. tmp_payment.payment_user_count,
    339. tmp_skucount.payment_sku_count,
    340. tmp_time.payment_avg_time
    341. from
    342. (
    343. select
    344. '$do_date' dt,
    345. sum(payment_count) payment_count,
    346. sum(payment_amount) payment_amount,
    347. sum(if(payment_count>0,1,0)) payment_user_count
    348. from ${APP}.dws_user_action_daycount
    349. where dt='$do_date'
    350. )tmp_payment
    351. join
    352. (
    353. select
    354. '$do_date' dt,
    355. sum(if(payment_count>0,1,0)) payment_sku_count
    356. from ${APP}.dws_sku_action_daycount
    357. where dt='$do_date'
    358. )tmp_skucount on tmp_payment.dt=tmp_skucount.dt
    359. join
    360. (
    361. select
    362. '$do_date' dt,
    363. sum(unix_timestamp(payment_time)-unix_timestamp(create_time))/count(*)/60 payment_avg_time
    364. from ${APP}.dwd_fact_order_info
    365. where dt='$do_date'
    366. and payment_time is not null
    367. )tmp_time on tmp_payment.dt=tmp_time.dt;
    368. with
    369. tmp_order as
    370. (
    371. select
    372. user_id,
    373. order_stats_struct.sku_id sku_id,
    374. order_stats_struct.order_count order_count
    375. from ${APP}.dws_user_action_daycount lateral view explode(order_detail_stats) tmp as order_stats_struct
    376. where date_format(dt,'yyyy-MM')=date_format('$do_date','yyyy-MM')
    377. ),
    378. tmp_sku as
    379. (
    380. select
    381. id,
    382. tm_id,
    383. category1_id,
    384. category1_name
    385. from ${APP}.dwd_dim_sku_info
    386. where dt='$do_date'
    387. )
    388. insert into table ${APP}.ads_sale_tm_category1_stat_mn
    389. select
    390. tm_id,
    391. category1_id,
    392. category1_name,
    393. sum(if(order_count>=1,1,0)) buycount,
    394. sum(if(order_count>=2,1,0)) buyTwiceLast,
    395. sum(if(order_count>=2,1,0))/sum( if(order_count>=1,1,0)) buyTwiceLastRatio,
    396. sum(if(order_count>=3,1,0)) buy3timeLast ,
    397. sum(if(order_count>=3,1,0))/sum( if(order_count>=1,1,0)) buy3timeLastRatio ,
    398. date_format('$do_date' ,'yyyy-MM') stat_mn,
    399. '$do_date' stat_date
    400. from
    401. (
    402. select
    403. tmp_order.user_id,
    404. tmp_sku.category1_id,
    405. tmp_sku.category1_name,
    406. tmp_sku.tm_id,
    407. sum(order_count) order_count
    408. from tmp_order
    409. join tmp_sku
    410. on tmp_order.sku_id=tmp_sku.id
    411. group by tmp_order.user_id,tmp_sku.category1_id,tmp_sku.category1_name,tmp_sku.tm_id
    412. )tmp
    413. group by tm_id, category1_id, category1_name;
    414. insert into table ${APP}.ads_area_topic
    415. select
    416. '$do_date',
    417. id,
    418. province_name,
    419. area_code,
    420. iso_code,
    421. region_id,
    422. region_name,
    423. login_day_count,
    424. order_day_count,
    425. order_day_amount,
    426. payment_day_count,
    427. payment_day_amount
    428. from ${APP}.dwt_area_topic;
    429. "
    430. $hive -e "$sql"

    2)增加脚本执行权限

    [atguigu@hadoop102 bin]$ chmod 777 dwt_to_ads.sh

    3)执行脚本导入数据

    [atguigu@hadoop102 bin]$ dwt_to_ads.sh 2020-06-15

    4)查看导入数据

    1. select * from ads_uv_count where dt='2020-06-15';
    2. select * from ads_new_mid_count;
    3. select * from ads_silent_count where dt='2020-06-15';
    4. select * from ads_back_count where dt='2020-06-15';
    5. select * from ads_wastage_count where dt='2020-06-15';
    6. select * from ads_user_retention_day_rate;
    7. select * from ads_continuity_wk_count where dt='2020-06-15';
    8. select * from ads_continuity_uv_count where dt='2020-06-15';
    9. select * from ads_user_topic where dt='2020-06-15';
    10. select * from ads_user_action_convert_day where dt='2020-06-15';
    11. select * from ads_product_info where dt='2020-06-15';
    12. select * from ads_product_sale_topN where dt='2020-06-15';
    13. select * from ads_product_favor_topN where dt='2020-06-15';
    14. select * from ads_product_cart_topN where dt='2020-06-15';
    15. select * from ads_product_refund_topN where dt='2020-06-15';
    16. select * from ads_appraise_bad_topN where dt='2020-06-15';
    17. select * from ads_order_daycount where dt='2020-06-15';
    18. select * from ads_payment_daycount where dt='2020-06-15';
    19. select * from ads_sale_tm_category1_stat_mn;
    20. select * from ads_area_topic where dt='2020-06-15';

    往ads层进行导入数据的时候,使用的是insert into,会导致每天出现一个新的文件,就是所谓的小文件,导致大量的小文件的生成.

    解决方式是:最直接的方式select * from 原来的 union 新的 overwrite 一下.因而这个任务就是可以重复执行.

    这个部分我配置的环境如下网盘所示(38.76G):
    链接:https://pan.baidu.com/s/19YzjgAMAqgIIrIUah4oFaQ?pwd=1111 
    提取码:1111 

  • 相关阅读:
    直播预告:防御升级-SMC2精准对抗账号劫持和漏洞威胁
    [RoarCTF 2019]Easy Calc
    Linux目录结构
    Spring Data JPA使用@DynamicUpdate注解进行Update部分更新
    适合学生党的蓝牙耳机有哪些?学生党蓝牙耳机推荐
    面试官最喜欢问的Redis知识
    14:00面试,14:06就出来了,问的问题有点变态。。。
    95后大厂程序员删库被判刑,只因项目被接手对领导心生不满
    (杂)网易云歌单导入到apple music
    《学习强国》投稿发稿全攻略:三种方式助你实现投稿梦想!
  • 原文地址:https://blog.csdn.net/m0_47489229/article/details/127465566