文章目录

  • 一、电商业务与数据结构简介
    • 1.1 电商业务流程图
    • 1.2 数据表结构
      • 1.2.1 电商常识 (SKU,SPU)
      • 1.2.2 订单表(order_info)
      • 订单详情表 (order_detail)
      • 1.2.4 商品表(sku_info)
      • 1.2.5 用户表(user_inf)
      • 1.2.6 商品一级分类表(base_category1)
      • 1.2.7 商品二级分类表(base_category2)
      • 1.2.8 商品三级分类表(base_category3)
      • 1.2.9 支付流水表(payment—_info)
  • 二、数仓理论
    • 2.1 什么是数据仓库
    • 2.2 表的分类
      • 2.2.1 实体表(事实表)
      • 2.2.2 维度表
      • 2.2.3 事务型事实表
      • 2.2.4 周期型事实表
    • 2.3 同步策略
      • 2.3.1 实体表同步策略
      • 2.3.2 维度表同步策略
      • 2.3.3 事务型事实表同步策略
      • 2.3.4 周期性事务表同步策略
    • 2.4 范式理论
      • 2.41 三范式区分
    • 2.5 数据仓库建模方式
      • 2.5.1 维度建模模型
    • 2.6 数据仓库分层
      • 2.6.1 为什么要分层
      • 2.6.2 数据仓库分层设计
  • 三 数仓搭建
    • 3.1 业务数据生成
      • 3.1.1 建表语句
      • 3.1.2 生成业务数据
    • 3.2 业务数据导入数仓
  • 四、数据导入
    • 1 Sqoop导入脚本
    • 2 ODS层
      • 2.1 创建订单表
      • 2.2 创建订单详情表
      • 2.3 创建商品表
      • 2.4 创建用户表
      • 2.5 创建支付流水表
      • 2.6 创建商品一级分类表
      • 2.7 创建商品二级分类表
      • 2.8 创建商品三级分类表
      • 2.9 ODS层数据导入脚本
    • 3 DWD层
      • 3.1 创建订单表
      • 3.2 创建订单详情表
      • 3.3 创建用户表
      • 3.4 创建支付流水表
      • 3.5 创建商品表(增加分类)
      • 3.6 DWD层数据导入脚本
    • 4 DWS层--用户行为宽表
      • 4.1 创建用户行为宽表
      • 4.2 DWS层用户行为数据宽表导入脚本
  • 五、GMV成交总额
    • 5.1 ADS层
      • 5.1.1 什么是GMV
      • 5.12 建表语句
      • 5.1.3数据导入
  • 六、转化率
    • 6.1 什么是转化率
    • 6.2 ADS层之新增用户占日活跃用户比率
      • 6.2.1 建表语句
      • 6.2.2 数据导入
  • 七、品牌复购率
    • 7.1 复购率计算分析
    • 7.2 DWS层
      • 7.2.1 用户购买商品明细表(宽表)
      • 7.2.2 数据导入
    • 7.3 ADS层
      • 7.3.1 建表语句
      • 7.3.2 数据导入
    • 7.4 品牌复购率结果输出到MySQL
  • 八、订单拉链表
    • 8.1 什么是订单拉链表
    • 8.2 为什么要做拉链表
    • 8.3 拉链表形成过程
    • 8.4拉链表制作过程图
    • 8.5 拉链表制作过程
      • 8.5.1 初始化拉链表,首次独立运行
      • 8.5.2 先制作当日变动(包括新增,修改)每日执行
      • 8.5.3 先合并变动信息,再追加新增信息 插入到临时表中
      • 8.5.4 把临时表覆盖给拉链表
  • 九、OLAP分析工具之Presto
    • 9.1 Presto Server安装
    • 9.2 Presto命令行
    • 9.3 Presto可视化Client安装
    • 9.4 Presto可视化操作
  • 十、Azkaban调度器
    • 10.1 复购率指标的产生的全调度流程

一、电商业务与数据结构简介

1.1 电商业务流程图

1.2 数据表结构

1.2.1 电商常识 (SKU,SPU)

SKU=Stock Keeping Unit(库存量单位)。即库存进出计量的基本单元,可以是以件,盒,托盘等为单位。SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法。现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。

SPU(Standard Product Unit):标准化产品单元。是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。

首先通过检索搜索出来的商品列表中,每个商品都是一个SKU。每个SKU都有自己独立的库存数。也就是说每一个商品详情展示都是一个SKU
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

1.2.2 订单表(order_info)

字段 含义
id 订单编号
total_amount 订单金额
ordere_status 订单状态
user_id 用户id
payment_way 支付方式
out_trade_no 支付流水号
create_time 创建时间
operate_time 操作时间

订单详情表 (order_detail)

字段 含义
id 订单编号
order_id 订单号
user_id 用户id
sku_id 商品id
sku_name 商品名称
order_price 下单价格
sku_num 商品数量
create_time 创建时间

1.2.4 商品表(sku_info)

字段 含义
id skuid
spu_id spuid
price 价格
sku_name 商品名称
sku_desc 商品描述
weight 重量
tm_id 品牌id
category3_id 品类id
create_time 创建时间

1.2.5 用户表(user_inf)

字段 含义
id 用户id
name 姓名
birthda 生日
gender 性别
email 邮箱
user_level 用户等级
create_time 创建时间

1.2.6 商品一级分类表(base_category1)

字段 含义
id id
name 名称

1.2.7 商品二级分类表(base_category2)

字段 含义
id id
name 名称
category1_id 一级品类id

1.2.8 商品三级分类表(base_category3)

字段 含义
id id
name 名称
category2_id 二级品类id

1.2.9 支付流水表(payment—_info)

字段 含义
id 编号
out_trade_no 对外业务编号
order_id 订单编号
user_id 用户编号
alipay_trade_no 支付宝交易流水编号
total_amount 支付金额
subject 交易内容
payment_type 支付类型
payment_time 支付时间

二、数仓理论

2.1 什么是数据仓库

官方解释:数据仓库(Data Warehouse)是一个面向主题的、集成的、稳定的且随时间变化的数据集合,用于支持管理人员的决策

几个特性

  • 面向主题:
    主题就是类型的意思。
    传统数据库主要是为应用程序进行数据处理,未必会按照同一主题存储数据;
    数据仓库侧重于数据分析工作,是按照主题存储的。
    这一点,类似于传统农贸市场与超市的区别,市场里面,针对一个商贩,他卖的萝卜、白菜这些蔬菜以及水果会在一个摊位上;而超市里,蔬菜和水果是分开的,并且在蔬菜里面也会进行分类,不同类型的蔬菜放到不同的地方。也就是说,农贸市场里的菜(数据)是按照商贩(应用程序)去归类(存储)的,而超市里面则是按照蔬菜、水果的类型(同主题)归类的。
  • 集成
    传统数据库通常与某些特定的应用相关,数据库之间相互独立。而数据仓库中的数据是在对原有分散的数据库数据抽取、清理的基础上经过系统加工、汇总和整理得到的,必须消除源数据中的不一致性,以保证数据仓库内的信息是关于整个企业的一致的全局信息。
  • 稳定
    稳定说的是相对稳定
    传统数据库中的数据通常实时更新,数据根据需要及时发生变化。数据仓库的数据主要供企业决策分析使用,所涉及的数据操作主要是数据查询,一旦某个数据进入数据仓库以后,一般情况下将被长期保留,也就是数据仓库中一般有大量的查询操作,但修改和删除操作很少,通常只需要定期的加载、刷新。
  • 变化
    这里的变化说的是反映历史变化
    传统数据库主要关心当前某一个时间段内的数据,而数据仓库中的数据通常包含历史信息,它里面记录了企业从过去某一时间点(如开始应用数据仓库的时间)到目前的各个阶段的信息,通过这些信息,可以对企业的发展历程和未来趋势做出分析和预测。

2.2 表的分类

2.2.1 实体表(事实表)

  • 定义
    指保存了大量业务数据的表,或者说保存了一些真实的行为数据的表
    例如:销售商品所产生的订单数据

2.2.2 维度表

  • 定义
    一般是指对应一些业务状态,代码的解释表。也可以称之为码表。例如:时间维度,地理区域维度,年龄维度,订单状态,支付方式,审批状态,商品分类等等。

2.2.3 事务型事实表

  • 定义
    事务型事实表,一般指随着业务发生不断产生的数据。特点是一旦发生不会再变化。
    一般比如,交易流水,操作日志,出库入库记录等等。
    支付流水表:

2.2.4 周期型事实表

  • 定义

周期型事实表,一般指随着业务发生不断产生的数据。
与事务型不同的是,数据会随着业务周期性的推进而变化。
比如订单,其中订单状态会周期性变化。再比如,请假、贷款申请,随着批复状态在周期性变化
订单表:

2.3 同步策略

数据同步策略的类型包括:全量表、增量表、新增及变化表、拉链表
全量表:存储全部的数据。
增量表:存储新增加的数据。
新增及变化表:存储新怎房价的数据和裱花的数据
拉链表:对新增及变化表做定期合并。

2.3.1 实体表同步策略

实体表:如用户、商品、商家、员工等
实体表数据量比较小:通常可以做每日全量。

2.3.2 维度表同步策略

维度表:如订单状态、审批状态、商品分类
维度表数据量比较小:通常做每日全量
注:
1)针对可能会有变化的状态数据可以存储每日全量
2)没变化的客观世界的维度(性别、地区、民族)可以存一份固定值。

2.3.3 事务型事实表同步策略

事务型事实表:交易流水、操作日志、出入库记录等
因为数据不会变化、且数据量大、可以做每日增量表、每天创建一个分区存储

2.3.4 周期性事务表同步策略

周期性事实表:订单、请假、贷款申请等。
这类表从数据量的角度,存每日全量的话、数据量太大、冗余也大。每日增量无法反应数据变化。
每日新增及变化量可以用,包括了当日的新增和修改。一般来说这个表,足够计算大部分当日数据的。但是这种依然无法解决能够得到某一个历史时间点(时间切片)的切片数据。
所以要用利用每日新增和变化表,制作一张拉链表,以方便的取到某个时间切片的快照数据。所以我们需要得到每日新增及变化量。

拉链表:

2.4 范式理论

关系型数据库设计时,遵照一定的规范要求,目的在于降低数据的冗余性,保证数据一致性,目前业界范式有:
第一范式(1NF)
第二范式(2NF)
第三范式(3NF)
巴斯-科德范式(BCNF)
第四范式(4NF)
第五范式(5NF)
不过后面那几种不太常见,数据库设计一般满足第三范式就足够了。

2.41 三范式区分

第一范式:数据库的每一列都是不可分割的原子数据项(属性不可分)
例:

学生id 姓名 性别 地址
001 渣渣辉 北京市朝阳区京望街10号

这里面存储的是学生信息
但是这里面的地址字段显然是不符合第一范式的,因为这里面的地址信息是可以拆分为省份+城市+街道信息的
所以针对这个字段进行拆分,让这个表满足第一范式

学生id 姓名 性别 省份 城市 街道
001 渣渣辉 北京市 朝阳区 京望街10号

第二范式(2NF)表示在1NF的基础上,数据库表中每一列都和主键相关,不能只和主键的某一部分相关(针对联合主键而言)
也就是说一个表中只能保存一种类型的数据,不可以把多种类型数据保存在同一张表中
如:

id 班级 班主任 课程 分数
001 计科1 渣渣辉 2001 98

这个表里面除了存储的有学生的班级信息,还有学生的考试成绩信息
根据我们刚才的分析,它是满足第一范式的,但是违背了第二范式,数据库表中的每一列并不是都和主键相关
所以我们为了让这个表满足第二范式,可以这样拆分:拆成两个表,一个表里面保存学生的班级信息,一个表里面保存学生的考试成绩信息

id 班级 班主任
001 计科1 渣渣辉
id 课程 分数
001 2001 98

注意:满足第三范式(3NF)必须先满足第二范式(2NF)。
第三范式(3NF): 要求一个数据库表中不包含已在其它表中包含的非主键字段,就是说,表中的某些字段信息,如果能够被推导出来,就不应该单独的设计一个字段来存放(能尽量外键join就用外键join)。很多时候,我们为了满足第三范式往往会把一张表拆分成多张表
来看下面这个案例,针对刚才满足了第二范式的表,其实还可以进行拆分

id 班级 班主任
001 计科1 渣渣辉
id 课程 分数
001 2001 98

可以再拆分为这样:

id 班级
001 计科1
班级 班主任
计科1 渣渣辉
id 课程 分数
001 2001 98

这样就满足数据库的第三范式了。

2.5 数据仓库建模方式

数据仓库建模方式
数据仓库建模可以使用多种方式
1:ER实体模型,这种模型其实就是满足数据库第三范式的模型,这就是刚才我们为什么要分析数据库中的三范式了。

ER模型是数据库设计的理论基础,当前几乎所有的OLTP系统设计都采用ER模型建模的方式
Bill Inom提出的数仓理论,推荐采用ER关系模型进行建模,不过这种方式在实际工作中不推荐使用。
2:维度建模模型
Ralph Kimball提出的数仓理论中,提出了维度建模,将数据仓库中的表划分为事实表和维度表。基于事实表和维度表进行维度建模。
维度建模通常又分为星型模型和雪花模型
维度建模是我们在构建数据仓库中常用的方式。
3:Data Vault模型
Data Vault是在ER模型的基础上衍生而来,模型设计的初衷是有效的组织基础数据层,使之易扩展、灵活的应对业务的变化,同时强调历史性、可追溯性和原子性,不要求对数据进行过度的一致性处理;并非针对分析场景所设计。
3:Anchor模型
Anchor是对Data Vault模型做了更近一步的规范化处理,初衷是为了设计高度可扩展的模型,核心思想是所有的扩张只添加而不修改,于是设计出的模型基本变成了k-v结构的模型。

2.5.1 维度建模模型

星型模型和雪花模型
星型模型和雪花模型主要区别就是对维度表的拆分,对于雪花模型,维度表的设计更加规范,一般符合3NF;
而星型模型,一般采用降维的操作,利用冗余来避免模型过于复杂,提高易用性和分析效率
先来看一下星型模型

这里面的中间的订单表是事实表,外面的四个是维度表。
这几个维度表,其实严格意义上来说,只能满足第二范式,是不满足第三范式的。但是这样的好处是查询效率比较高,在查询的时候不需要关联很多张表。缺点就是数据有冗余。使用这个五角星代表星型模型还是比较形象的,因为针对事实表周边的这些维度表,外层就没有其它的表
了。
接下来看一下雪花模型

这个里面订单表是一个事实表,其余的都是维度表。针对商品维度表外层又拆分出来了一个商品类目的维度表,这样拆分之后其实就满足第三范式了,但是这样就变的复杂了,后期在获取商品维度数据的时候,还需要关联这个商品类目维度表。
这里使用这个雪花代表雪花模型也是比较形象的,事实表周边会有一层维度表,这些维度表外层还可能会有多层维度表
两种模型的优缺点总结
星型模型 VS 雪花模型
冗余:雪花模型符合业务逻辑设计,采用3NF设计,有效降低数据冗余;星型模型的维度表设计不符合3NF,反规范化,维度表之间不会直接相关,牺牲部分存储空间

性能:雪花模型由于存在维度间的关联,采用3NF降低冗余,通常在使用过程中,需要连接更多的维度表,导致性能偏低;星型模型违反三范式,采用降维的操作将维度整合,以存储空间为代价有效降低维度表连接数,性能比雪花模型高

在实际工作中我们多采用星型模型,因为数据仓库主要是侧重于做数据分析,对数据的查询性能要求比较
高,所以星型模型是比较好的选择,在实际工工作中我们会尽可能的多构建一些宽表,提前把多种有关联
的维度整合到一张表中,后期使用时就不需要多表关联了,比较方便,并且性能也高。

2.6 数据仓库分层

2.6.1 为什么要分层

数据仓库在构建过程中通常都需要进行分层处理,业务不同,分层的技术处理手段也不同,对数据进行分层的一个主要原因就是希望在管理数据的时候。能对数据有一个更加清晰的掌控
主要有下边几个原因:
1)清晰的数据结构:每一个分层的数据都有它的作用域,这样我们在使用表的时候能更方便地定位和理解。
2)数据血缘追踪:简单来讲可以这样理解,我们最终给业务方呈现的是一个能直接使用的业务表,但是它的来源有很多,如果有一张来源表出问题了,我们希望能够快速准确地定位到问题,并清楚它的危害范围,分层之后就很好定位问题,以及可以清晰的知道它的危害范围
3) 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少重复计算。
4)把复杂问题简单化:将一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性, 当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。

2.6.2 数据仓库分层设计


数据仓库一般会分为4层
1)ODS层:原始数据层,数据源中的数据,采集过来之后,原样保存
2)DWD层:明细数据层:这一层对ODS层的数据进行清洗,解决一些数据质量问题和数据的完整度问题。
3)DWS层:这一层是对DWD层的数据进行轻度聚合汇总,生成一系列的中间件,提升公共指标的复用性,减少重复加工,并且构建出来一些宽表,用于提供后续的业务查询
4) APP层(ads):根据业务需要,由前面三层的数据统计而出的结果,可以直接提供查询展现,一般会把APP层的数据导出到MySQL中供线上系统使用,提供报表展示、数据监控及其它功能。也有公司把这层称为DM层。虽然名字不一样,但是性质是一样的。

注意:针对DWD层在对数据进行清洗的时候,一般需要遵循以下原则

  1. 数据唯一性校验(通过数据采集工具采集的数据会存在重复的可能性)
  2. 数据完整性校验(采集的数据中可能会出现缺失字段的情况,针对缺失字段的数据建议直接丢掉,如果可以确定是哪一列缺失也可以进行补全,可以用同一列上的前一个数据来填补或者同一列上的后一个数据来填补)
  3. 数据合法性校验-1(针对数字列中出现了null、或者-之类的异常值,全部替换为一个特殊值,例如0或者-1,这个需要根据具体的业务场景而定)
  4. 数据合法性校验-2(针对部分字段需要校验数据的合法性,例如:用户的年龄,不能是负数)
    代码如下(示例):

三 数仓搭建

3.1 业务数据生成

创建数据库

create database gmall;

3.1.1 建表语句

 CREATE TABLE `order_info` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`consignee` VARCHAR(100) DEFAULT NULL COMMENT '收货人',`consignee_tel` VARCHAR(20) DEFAULT NULL COMMENT '收件人电话',`total_amount` DECIMAL(10,2) DEFAULT NULL COMMENT '总金额',`order_status` VARCHAR(20) DEFAULT NULL COMMENT '订单状态',`user_id` BIGINT(20) DEFAULT NULL COMMENT '用户id',`payment_way` VARCHAR(20) DEFAULT NULL COMMENT '付款方式',`delivery_address` VARCHAR(1000) DEFAULT NULL COMMENT '送货地址',`order_comment` VARCHAR(200) DEFAULT NULL COMMENT '订单备注',`out_trade_no` VARCHAR(50) DEFAULT NULL COMMENT '订单交易编号(第三方支付用)',`trade_body` VARCHAR(200) DEFAULT NULL COMMENT '订单描述(第三方支付用)',`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',`operate_time` DATETIME DEFAULT NULL COMMENT '操作时间',`expire_time` DATETIME DEFAULT NULL COMMENT '失效时间',`tracking_no` VARCHAR(100) DEFAULT NULL COMMENT '物流单编号',`parent_order_id` BIGINT(20) DEFAULT NULL COMMENT '父订单编号',`img_url` VARCHAR(200) DEFAULT NULL COMMENT '图片路径',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='订单表 订单表';DROP TABLE IF EXISTS sku_info;CREATE TABLE `sku_info` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '库存id(itemID)',`spu_id` BIGINT(20) DEFAULT NULL COMMENT '商品id',`price` DECIMAL(10,0) DEFAULT NULL COMMENT '价格',`sku_name` VARCHAR(200) DEFAULT NULL COMMENT 'sku名称',`sku_desc` VARCHAR(2000) DEFAULT NULL COMMENT '商品规格描述',`weight` DECIMAL(10,2) DEFAULT NULL COMMENT '重量',`tm_id` BIGINT(20) DEFAULT NULL COMMENT '品牌(冗余)', `category3_id` BIGINT(20) DEFAULT NULL COMMENT '三级分类id(冗余)',`sku_default_img` VARCHAR(200) DEFAULT NULL COMMENT '默认显示图片(冗余)',`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8 COMMENT='库存单元表';CREATE TABLE `user_info` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`login_name` VARCHAR(200) DEFAULT NULL COMMENT '用户名称',`nick_name` VARCHAR(200) DEFAULT NULL COMMENT '用户昵称',`passwd` VARCHAR(200) DEFAULT NULL COMMENT '用户密码',`name` VARCHAR(200) DEFAULT NULL COMMENT '用户姓名',`phone_num` VARCHAR(200) DEFAULT NULL COMMENT '手机号',`email` VARCHAR(200) DEFAULT NULL COMMENT '邮箱',`head_img` VARCHAR(200) DEFAULT NULL COMMENT '头像',`user_level` VARCHAR(200) DEFAULT NULL COMMENT '用户级别',`birthday` DATE DEFAULT NULL COMMENT '用户生日',`gender` VARCHAR(1) DEFAULT NULL COMMENT '性别 M男,F女',`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=9501 DEFAULT CHARSET=utf8 COMMENT='用户表';CREATE TABLE `order_detail` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`order_id` BIGINT(20) DEFAULT NULL COMMENT '订单编号',`sku_id` BIGINT(20) DEFAULT NULL COMMENT 'sku_id',`sku_name` VARCHAR(200) DEFAULT NULL COMMENT 'sku名称(冗余)',`img_url` VARCHAR(200) DEFAULT NULL COMMENT '图片名称(冗余)',`order_price` DECIMAL(10,2) DEFAULT NULL COMMENT '购买价格(下单时sku价格)',`sku_num` VARCHAR(200) DEFAULT NULL COMMENT '购买个数',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=55750 DEFAULT CHARSET=utf8 COMMENT='订单明细表';DROP TABLE  IF EXISTS `payment_info`;
CREATE   TABLE  `payment_info`
(`id`            BIGINT NOT NULL AUTO_INCREMENT COMMENT '编号',`out_trade_no`   VARCHAR(20) COMMENT '对外业务编号',`order_id`         VARCHAR(20)  COMMENT '订单编号',`user_id`          VARCHAR(20) COMMENT '用户编号',`alipay_trade_no`  VARCHAR(20)  COMMENT '支付宝交易流水编号',`total_amount`    DECIMAL(16,2) COMMENT '支付金额',`subject`          VARCHAR(20)  COMMENT '交易内容',`payment_type`          VARCHAR(20)  COMMENT '支付方式',`payment_time`    VARCHAR(20) COMMENT '支付时间',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=55750 DEFAULT CHARSET=utf8 COMMENT='支付流水表';CREATE TABLE  `base_category1`
(`id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',`name`            VARCHAR(10) NOT NULL COMMENT '分类名称'
);
ALTER TABLE `base_category1` COMMENT= '一级分类表';CREATE TABLE  `base_category2`
(`id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',`name`            VARCHAR(200) NOT NULL COMMENT '二级分类名称',`category1_id`     BIGINT COMMENT '一级分类编号'
);
ALTER TABLE `base_category2` COMMENT= '二级分类表';CREATE TABLE  `base_category3`
(`id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',`name`            VARCHAR(200) NOT NULL COMMENT '三级分类名称',`category2_id`     BIGINT COMMENT '二级分类编号'
);
ALTER TABLE `base_category3` COMMENT= '三级分类表';
#####

3.1.2 生成业务数据

1)生成业务数据函数说明
init_data ( do_date_string VARCHAR(20) , order_incr_num INT, user_incr_num INT , sku_num INT , if_truncate BOOLEAN ):

   参数一:do_date_string生成数据日期参数二:order_incr_num订单id个数参数三:user_incr_num用户id个数参数四:sku_num商品sku个数参数五:if_truncate是否参数数据
 DELIMITER $$DROP PROCEDURE IF EXISTS `insert_sku`$$
##新增max_num个sku
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_sku`( create_time_string VARCHAR(200),max_num INT  )
BEGIN  DECLARE v_create_time DATETIME DEFAULT NULL;DECLARE i INT DEFAULT 0;SET autocommit = 0;    REPEAT  SET i = i + 1;  SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(1,3600*24) SECOND); INSERT INTO sku_info (spu_id,price,sku_name,sku_desc,weight,tm_id,category3_id,sku_default_img,create_time  ) VALUES (rand_num(1,1000) ,rand_num(10,5000) , rand_string(20), rand_string(30),CAST(rand_num(50,500) AS DECIMAL(10,2))/100.0  ,rand_num(1,100),  rand_num(1,5000),CONCAT('http://',rand_string(40)), v_create_time    ); UNTIL i = max_num  END REPEAT;  COMMIT;  END$$DELIMITER ;DELIMITER $$DROP PROCEDURE IF EXISTS `insert_user`$$
#随机产生max_num个用户
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_user`( create_time_string VARCHAR(200),max_num INT  )
BEGIN  DECLARE v_create_time DATETIME DEFAULT NULL;DECLARE i INT DEFAULT 0;DECLARE v_birthday DATE DEFAULT 0;DECLARE v_gender VARCHAR(1) DEFAULT NULL;SET autocommit = 0;    REPEAT  SET i  = i + 1;  SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(1,3600*24) SECOND); SET v_birthday=DATE_ADD(DATE_FORMAT('1950-01-01','%Y-%m-%d') ,INTERVAL rand_num(1,365*50) DAY); SET v_gender=IF(rand_num(0,1)=0,'M','F');INSERT INTO user_info (login_name,nick_name,passwd,NAME,phone_num,email,head_img,user_level,birthday,gender,create_time  ) VALUES (rand_string(20) ,rand_string(20) , CONCAT('pwd',rand_string(20)), rand_string(30), CONCAT('13',rand_nums(0,9,9,''))    ,CONCAT(rand_string(8),'@',rand_string(3),'.com') ,  CONCAT('http://',rand_string(40)), rand_num(1,5),v_birthday,v_gender,v_create_time    ); UNTIL i = max_num  END REPEAT;  COMMIT;  END$$DELIMITER ;DELIMITER $$DROP PROCEDURE IF EXISTS `insert_order`$$
##生成订单
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_order`( create_time_string VARCHAR(200),max_num INT,user_num INT ,sku_num INT  )
BEGIN  DECLARE v_create_time DATETIME DEFAULT NULL;DECLARE i INT DEFAULT 0;DECLARE v_order_status INT DEFAULT 0;  DECLARE v_operate_time DATETIME DEFAULT NULL; DECLARE v_order_id INT DEFAULT NULL; DECLARE v_order_detail_num INT DEFAULT NULL; DECLARE j INT DEFAULT 0;SET autocommit = 0;    REPEAT  SET i = i + 1;  SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(30,3600*23) SECOND);SET v_order_status=rand_num(1,2); ## IF v_order_status>1 THEN SET v_operate_time= DATE_ADD(v_create_time ,INTERVAL rand_num(30,3600) SECOND);ELSE SET v_operate_time=NULL  ;END IF ;INSERT INTO order_info (consignee, consignee_tel,total_amount ,order_status ,user_id,payment_way,delivery_address,order_comment,out_trade_no,trade_body,create_time,operate_time,expire_time, tracking_no,parent_order_id ,img_url) VALUES (rand_string(6) , CONCAT('13',rand_nums(0,9,9,'')),CAST(rand_num(50,1000) AS DECIMAL(10,2)) ,v_order_status ,rand_num(1,user_num), rand_num(1,2),rand_string(20),rand_string(20),rand_nums(0,9,10,''),'',v_create_time, v_operate_time,NULL,NULL,NULL,NULL ); SELECT  LAST_INSERT_ID() INTO v_order_id ;SET v_order_detail_num=rand_num(1,5); WHILE j<v_order_detail_num DOSET j=j+1;INSERT INTO  order_detail  (order_id , sku_id,sku_name ,img_url ,order_price,sku_num ) VALUES (v_order_id , rand_num(1,sku_num),rand_string(10),CONCAT('http://',rand_string(40)) ,CAST(rand_num(20,5000) AS DECIMAL(10,2)), rand_num(1,5)  ); END WHILE;SET j=0;UNTIL i = max_num  END REPEAT;  COMMIT;  END$$DELIMITER ;DELIMITER $$DROP PROCEDURE IF EXISTS `update_order`$$
## 随机让订单状态小于5的订单 发生状态改变
CREATE DEFINER=`root`@`localhost` PROCEDURE `update_order`(operate_time_string VARCHAR(20))
BEGIN DECLARE v_operate_time DATETIME DEFAULT NULL; SET v_operate_time=DATE_FORMAT(operate_time_string,'%Y-%m-%d');
UPDATE order_info o SET   o.`order_status`=o.`order_status`+rand_num_seed(0,1,o.id) ,operate_time= IF( rand_num_seed(0,1,o.id) >0 , DATE_ADD(v_operate_time ,INTERVAL rand_num(30,20*3600) SECOND),operate_time)
WHERE o.`order_status`<5;
END$$DELIMITER ;DELIMITER$$DROP PROCEDURE IF EXISTS `insert_payment`$$## 只要订单状态更新为2 ,给当天插入一条支付信息 CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_payment`( do_date_str VARCHAR(200)   )
BEGIN      INSERT INTO payment_info (out_trade_no,order_id,user_id,alipay_trade_no,total_amount,`subject`,payment_type,payment_time  ) SELECT o.out_trade_no,o.id,user_id,CONCAT( rand_string(4),'-',rand_nums(0,9,8,'')) alipay_trade_no,o.total_amount,rand_string(8) `subject`,( CASE rand_num(1,3) WHEN 1 THEN  'wechatpay' WHEN 2 THEN 'alipay' WHEN 3 THEN 'unionpay' END) payment_type , IF(o.operate_time IS NULL,o.create_time,o.operate_time) payment_timeFROM order_info  o WHERE (DATE_FORMAT(o.create_time,'%Y-%m-%d')= do_date_str OR DATE_FORMAT(o.operate_time,'%Y-%m-%d')= do_date_str ) AND o.order_status='2';COMMIT;END$$DELIMITER ;DELIMITER $$CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_base3`()
BEGIN DECLARE max_num SMALLINT DEFAULT 0;DECLARE base3_id INT DEFAULT 0;DECLARE i SMALLINT DEFAULT 0;select COUNT(DISTINCT(category3_id)) into max_num from sku_info;SET autocommit = 0;REPEAT select p.id into base3_id from (select DISTINCT(category3_id) id from sku_info order by category3_id desc limit i,1) as p;insert IGNORE into base_category3(id,name,category2_id) VALUES (base3_id,rand_string(2),rand_num_seed(1,100,base3_id));set i=i+1;until i > max_numEND REPEAT;COMMIT;
END
DELIMITER ;DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_base2`()
BEGIN DECLARE max_num SMALLINT DEFAULT 0;DECLARE base3_id INT DEFAULT 0;DECLARE i SMALLINT DEFAULT 0;select COUNT(DISTINCT(category2_id)) into max_num from base_category3;SET autocommit = 0;REPEAT select p.id into base3_id from (select DISTINCT(category2_id) id from base_category3 order by category2_id DESC limit i,1) as p;insert IGNORE into base_category2(id,name,category1_id) VALUES (base3_id,rand_string(1),rand_num_seed(1,20,base3_id));set i=i+1;until i > max_numEND REPEAT;COMMIT;
END
DELIMITER ;DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_base1`()
BEGIN DECLARE max_num SMALLINT DEFAULT 0;DECLARE base_id INT DEFAULT 0;DECLARE i SMALLINT DEFAULT 0;select COUNT(DISTINCT(category1_id)) into max_num from base_category2;SET autocommit = 0;REPEAT select p.id into base_id from (select DISTINCT(category1_id) id from base_category2 order by category1_id_id DESC limit i,1) as p;insert IGNORE into base_category1(id,name) VALUES (base3_id,rand_string(1));set i=i+1;until i > max_numEND REPEAT;COMMIT;
END
DELIMITER ;DELIMITER $$DROP PROCEDURE IF EXISTS `init_data`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `init_data`( do_date_string VARCHAR(20) ,order_incr_num INT,user_incr_num INT ,sku_num INT ,if_truncate BOOLEAN  )
BEGIN  DECLARE user_count INT DEFAULT 0; DECLARE sku_count INT DEFAULT 0; DECLARE do_date VARCHAR(20) DEFAULT do_date_string;IF if_truncate  THEN TRUNCATE TABLE order_info ;TRUNCATE TABLE order_detail ;TRUNCATE TABLE sku_info ;TRUNCATE TABLE user_info ;END IF ;     CALL insert_sku(do_date,sku_num );SELECT COUNT(*) INTO sku_count FROM  sku_info;CALL insert_user(do_date,user_incr_num );SELECT COUNT(*) INTO user_count FROM  user_info;CALL update_order(do_date);CALL insert_order(do_date,order_incr_num,user_count,sku_count);CALL insert_payment(do_date);CALL insert_base3();CALL insert_base2();CALL insert_base1();END$$DELIMITER ;

几个辅助函数


DELIMITER $$
CREATE DEFINER = `root`@`localhost` FUNCTION `rand_num`(`min` bigint,`max` bigint)
-- DETERMINISTICRETURNS bigint
BEGINDECLARE result BIGINT DEFAULT 0;SET result = ROUND(RAND()*(max-min)+min);RETURN result;
END$$DELIMITER ;DELIMITER $$DROP FUNCTION IF EXISTS rand_nums$$
CREATE DEFINER = `root`@`localhost` FUNCTION `rand_nums`(`start` bigint,`end` bigint,`num` BIGINT,`concat_string` varchar(5))RETURNS varchar(255)BEGINDECLARE result varchar(255) DEFAULT '';DECLARE i INT DEFAULT 0;REPEATSET result = CONCAT(result,CONCAT(rand_num(start,end)-1,concat_string));SET i = i + 1;UNTIL i > numEND REPEAT;RETURN result;END$$
DELIMITER ;DELIMITER $$DROP FUNCTION IF EXISTS rand_num_seed$$CREATE DEFINER= `root`@`localhost` FUNCTION `rand_num_seed`(`min` bigint,`max` bigint,`seed` bigint)RETURNS bigintBEGINDECLARE result bigint DEFAULT 0;SET result = ROUND(rand(seed)*(max-min)+min);RETURN result;END$$
DELIMITER ;DELIMITER $$
DROP FUNCTION IF EXISTS rand_string$$
create DEFINER = `root`@`localhost` FUNCTION rand_string(strlen SMALLINT ) RETURNS VARCHAR(255)
BEGIN
DECLARE randStr VARCHAR(255) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
DECLARE i SMALLINT DEFAULT 0;
DECLARE resultStr VARCHAR(255) DEFAULT '';
WHILE i<strlen DO
SET resultStr=CONCAT(SUBSTR(randStr,FLOOR(RAND()*LENGTH(randStr))+1,1),resultStr);
SET i=i+1;
END WHILE;
RETURN resultStr;
END$$ DELIMITER ;DELIMITER $$
DROP FUNCTION IF EXISTS rand_category_name$$
create DEFINER = `root`@`localhost` FUNCTION rand_category_name(i SMALLINT) RETURNS VARCHAR(10)
BEGIN
DECLARE randStr VARCHAR(255) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
DECLARE result VARCHAR(10) DEFAULT '';
SET result=SUBSTR(randStr,i,1);
RETURN result;
END$$DELIMITER ;DELIMITER $$
DROP FUNCTION IF EXISTS base_id$$
CREATE DEFINER = `root`@`localhost` FUNCTION base_id(FIELD_NAME VARCHAR(100),TABLE_NAME VARCHAR(100),START INT ) RETURNS INT
BEGIN
RETURN call `base_id`(FIELD_NAME,TABLE_NAME,START);
END $$
DELIMITER;

2)生成测试数据:
(1)

CALL init_data('2021-07-10',1000,200,300,FALSE);
CALL init_data('2021-07-11',1000,200,300,FALSE);

3.2 业务数据导入数仓

四、数据导入

Sqoop安装参考:https://blog.csdn.net/weixin_44815022/article/details/119804588

1 Sqoop导入脚本

1)在/workspace/hive/gmall/sqoop目录创建gmall_import.sh

vi /workspace/hive/gmall/sqoop/gmall_import.sh

添加如下内容

#!/bin/bashdb_date=$2
echo $db_date
db_name=gmallimport_data() {sqoop import \--connect jdbc:mysql://hostname:3306/$db_name?serverTimezone=Asia/Shanghai \
--username root \
--password mysql \
--target-dir  /origin_data/$db_name/db/$1/$db_date \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query   "$2"' and  $CONDITIONS;'
}import_sku_info(){import_data  "sku_info"  "select
id, spu_id, price, sku_name, sku_desc, weight, tm_id,
category3_id, create_time from sku_info  where 1=1"
}import_user_info(){import_data "user_info" "select
id, name, birthday, gender, email, user_level,
create_time
from user_info where 1=1"
}import_base_category1(){import_data "base_category1" "select
id, name from base_category1 where 1=1"
}import_base_category2(){import_data "base_category2" "select
id, name, category1_id from base_category2 where 1=1"
}import_base_category3(){import_data "base_category3" "select id, name, category2_id from base_category3 where 1=1"
}import_order_detail(){import_data   "order_detail"   "select od.id, order_id, user_id, sku_id, sku_name, order_price, sku_num, o.create_time  from order_info o,order_detail od where o.id=od.order_id and DATE_FORMAT(o.create_time,'%Y-%m-%d')='$db_date'"
}import_payment_info(){import_data  "payment_info"   "select id,  out_trade_no, order_id, user_id, alipay_trade_no, total_amount,  subject , payment_type, payment_time from payment_info where DATE_FORMAT(payment_time,'%Y-%m-%d')=$db_date"
}import_order_info(){import_data   "order_info"   "select id, total_amount, order_status, user_id, payment_way, out_trade_no, create_time, operate_time  from order_info where (DATE_FORMAT(create_time,'%Y-%m-%d')='$db_date' or DATE_FORMAT(operate_time,'%Y-%m-%d')='$db_date')"
}case $1 in"base_category1")import_base_category1
;;"base_category2")import_base_category2
;;"base_category3")import_base_category3
;;"order_info")import_order_info
;;"order_detail")import_order_detail
;;"sku_info")import_sku_info
;;"user_info")import_user_info
;;"payment_info")import_payment_info
;;"all")import_base_category1import_base_category2import_base_category3import_order_infoimport_order_detailimport_sku_infoimport_user_infoimport_payment_info
;;
esac

2) 修改权限

chmod 777 gmall_import.sh

3)执行脚本导入数据

sqoop_import.sh all 2021-07-10
sqoop_import.sh all 2021-07-11

2 ODS层

和业务数据库中的一样

2.1 创建订单表

hive (gmall)>
drop table if exists ods_order_info;
create table ods_order_info ( `id` string COMMENT '订单编号',`total_amount` decimal(10,2) COMMENT '订单金额', `order_status` string COMMENT '订单状态', `user_id` string COMMENT '用户id' ,`payment_way` string COMMENT '支付方式',  `out_trade_no` string COMMENT '支付流水号',  `create_time` string COMMENT '创建时间',  `operate_time` string COMMENT '操作时间'
) COMMENT '订单表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_order_info/'
tblproperties ("parquet.compression"="snappy")
;

2.2 创建订单详情表

hive (gmall)>
drop table if exists ods_order_detail;
create table ods_order_detail( `id` string COMMENT '订单编号',`order_id` string  COMMENT '订单号', `user_id` string COMMENT '用户id' ,`sku_id` string COMMENT '商品id',  `sku_name` string COMMENT '商品名称',  `order_price` string COMMENT '下单价格',  `sku_num` string COMMENT '商品数量',  `create_time` string COMMENT '创建时间'
) COMMENT '订单明细表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_order_detail/'
tblproperties ("parquet.compression"="snappy")
;

2.3 创建商品表

hive (gmall)>
drop table if exists ods_sku_info;
create table ods_sku_info( `id` string COMMENT 'skuId',`spu_id` string   COMMENT 'spuid', `price` decimal(10,2) COMMENT '价格' ,`sku_name` string COMMENT '商品名称',  `sku_desc` string COMMENT '商品描述',  `weight` string COMMENT '重量',  `tm_id` string COMMENT '品牌id',  `category3_id` string COMMENT '品类id',  `create_time` string COMMENT '创建时间'
) COMMENT '商品表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_sku_info/'
tblproperties ("parquet.compression"="snappy")
;

2.4 创建用户表

hive (gmall)>
drop table if exists ods_user_info;
create table ods_user_info( `id` string COMMENT '用户id',`name`  string COMMENT '姓名', `birthday` string COMMENT '生日' ,`gender` string COMMENT '性别',  `email` string COMMENT '邮箱',  `user_level` string COMMENT '用户等级',  `create_time` string COMMENT '创建时间'
) COMMENT '用户信息'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_user_info/'
tblproperties ("parquet.compression"="snappy")
;

2.5 创建支付流水表

hive (gmall)>
drop table if exists `ods_payment_info`;
create table  `ods_payment_info`(`id`   bigint COMMENT '编号',`out_trade_no`    string COMMENT '对外业务编号',`order_id`        string COMMENT '订单编号',`user_id`         string COMMENT '用户编号',`alipay_trade_no` string COMMENT '支付宝交易流水编号',`total_amount`    decimal(16,2) COMMENT '支付金额',`subject`         string COMMENT '交易内容',`payment_type` string COMMENT '支付类型',`payment_time`   string COMMENT '支付时间')  COMMENT '支付流水表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_payment_info/'
tblproperties ("parquet.compression"="snappy")
;

2.6 创建商品一级分类表

hive (gmall)>
drop table if exists ods_base_category1;
create table ods_base_category1( `id` string COMMENT 'id',`name`  string COMMENT '名称'
) COMMENT '商品一级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_base_category1/'
tblproperties ("parquet.compression"="snappy")
;

2.7 创建商品二级分类表

hive (gmall)>
drop table if exists ods_base_category2;
create external table ods_base_category2( `id` string COMMENT ' id',`name`  string COMMENT '名称',category1_id string COMMENT '一级品类id'
) COMMENT '商品二级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_base_category2/'
tblproperties ("parquet.compression"="snappy")
;

2.8 创建商品三级分类表

hive (gmall)>
drop table if exists ods_base_category3;
create table ods_base_category3( `id` string COMMENT ' id',`name`  string COMMENT '名称',category2_id string COMMENT '二级品类id'
) COMMENT '商品三级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ods/ods_base_category3/'
tblproperties ("parquet.compression"="snappy")
;

2.9 ODS层数据导入脚本

1)在/workspace/hive/gmall/hive目录创建init_ods.sh

vi init_ods.sh

编写如下内容

#!/bin/bashdo_date=$1
APP=gmallsql="
load data inpath '/origin_data/$APP/db/order_info/$do_date' OVERWRITE into table $APP.ods_order_info partition(dt='$do_date');load data inpath '/origin_data/$APP/db/order_detail/$do_date' OVERWRITE into table $APP.ods_order.detail partition(dt='$do_date');load data inpath '/origin_data/$APP/db/sku_info/$do_date'  OVERWRITE into table $APP"".ods_sku_info partition(dt='$do_date');load data inpath '/origin_data/$APP/db/user_info/$do_date' OVERWRITE into table $APP"".ods_user_info partition(dt='$do_date');load data inpath '/origin_data/$APP/db/payment_info/$do_date' OVERWRITE into table $APP"".ods_payment_info partition(dt='$do_date');load data inpath '/origin_data/$APP/db/base_category1/$do_date' OVERWRITE into table $APP"".ods_base_category1 partition(dt='$do_date');load data inpath '/origin_data/$APP/db/base_category2/$do_date' OVERWRITE into table $APP"".ods_base_category2 partition(dt='$do_date');load data inpath '/origin_data/$APP/db/base_category3/$do_date' OVERWRITE into table $APP"".ods_base_category3 partition(dt='$do_date'); "
hive -e "$sql"

2)增加脚本执行权限

chmod 777 init_ods.sh

3)执行脚本导入数据

init_ods.sh 2021-07-10
init_ods.sh 2021-07-11

4)查询导入数据

hive (gmall)>
select * from ods_order_info where dt='2021-07-10' limit 1;
select * from ods_order_info where dt='2021-07-11' limit 1;

3 DWD层

基于ODS层对数据镜像判空过滤,对商品分类表进行维度退化(降维)。

3.1 创建订单表

hive(gmall)>
drop table if exists dwd_order_info;
create external table dwd_order_info(`id` string COMMENT '',`total_amount` decimal(10,2) COMMENT '', `order_status` string COMMENT ' 1 2  3  4  5', `user_id` string COMMENT 'id' ,`payment_way` string COMMENT '',  `out_trade_no` string COMMENT '',  `create_time` string COMMENT '',  `operate_time` string COMMENT ''
) COMMENT ''
PARTITION BY (`dt` string)
stored as parquet
location '/warehouse/gmall/dwd/dwd_order_info/'
tblproperties ("parquet.compression"="snappy")
;

3.2 创建订单详情表

hive (gmall)>
drop table if exists dwd_order_detail;
create external table dwd_order_detail( `id` string COMMENT '',`order_id` decimal(10,2) COMMENT '', `user_id` string COMMENT 'id' ,`sku_id` string COMMENT 'id',  `sku_name` string COMMENT '',  `order_price` string COMMENT '',  `sku_num` string COMMENT '', `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_detail/'
tblproperties ("parquet.compression"="snappy")
;

3.3 创建用户表

hive (gmall)>
drop table if exists dwd_user_info;
create external table dwd_user_info( `id` string COMMENT 'id',`name`  string COMMENT '', `birthday` string COMMENT '' ,`gender` string COMMENT '',  `email` string COMMENT '',  `user_level` string COMMENT '',  `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_user_info/'
tblproperties ("parquet.compression"="snappy")
;

3.4 创建支付流水表

hive (gmall)>
drop table if exists `dwd_payment_info`;
create external  table  `dwd_payment_info`(`id`   bigint COMMENT '',`out_trade_no`   string COMMENT '',`order_id`        string COMMENT '',`user_id`         string COMMENT '',`alipay_trade_no` string COMMENT '',`total_amount`    decimal(16,2) COMMENT '',`subject`         string COMMENT '',`payment_type` string COMMENT '',`payment_time`   string COMMENT '')  COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_payment_info/'
tblproperties ("parquet.compression"="snappy")
;

3.5 创建商品表(增加分类)

hive (gmall)>
drop table if exists dwd_sku_info;
create external table dwd_sku_info( `id` string COMMENT 'skuId',`spu_id` string COMMENT 'spuid', `price` decimal(10,2) COMMENT '' ,`sku_name` string COMMENT '',  `sku_desc` string COMMENT '',  `weight` string COMMENT '',  `tm_id` string COMMENT 'id',  `category3_id` string COMMENT '1id',  `category2_id` string COMMENT '2id',  `category1_id` string COMMENT '3id',  `category3_name` string COMMENT '3',  `category2_name` string COMMENT '2',  `category1_name` string COMMENT '1',  `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_sku_info/'
tblproperties ("parquet.compression"="snappy")
;

3.6 DWD层数据导入脚本

1)在/workspace/hive/gmall/hive目录创建init_dwd.sh

vi init_dwd.sh

编写如下内容

#!/bin/bashAPP=gmall# 获取日期
if [ -n $1 ] ;thenlog_date=$1
else
# 当前日期的前一天log_date=`date -d "-1 day" +%F`
fisql="
set hive.exec.dynamic.partition.mode=nonstrict;insert  overwrite table   "$APP".dwd_order_info partition(dt)
select  * from "$APP".ods_order_info
where dt='$log_date'  and id is not null;insert  overwrite table   "$APP".dwd_order_detail partition(dt)
select  * from "$APP".ods_order_detail
where dt='$log_date'   and id is not null;insert  overwrite table   "$APP".dwd_user_info partition(dt)
select  * from "$APP".ods_user_info
where dt='$log_date'   and id is not null;insert  overwrite table   "$APP".dwd_payment_info partition(dt)
select  * from "$APP".ods_payment_info
where dt='$log_date'  and id is not null;insert  overwrite table   "$APP".dwd_sku_info partition(dt)
select  sku.id,sku.spu_id, sku.price,sku.sku_name,  sku.sku_desc,  sku.weight,  sku.tm_id,  sku.category3_id,  c2.id category2_id ,  c1.id category1_id,  c3.name category3_name,  c2.name category2_name,  c1.name category1_name,  sku.create_time,sku.dt
from"$APP".ods_sku_info sku
join "$APP".ods_base_category3 c3 on sku.category3_id=c3.id join "$APP".ods_base_category2 c2 on c3.category2_id=c2.id join "$APP".ods_base_category1 c1 on c2.category1_id=c1.id
where sku.dt='$log_date'  and c2.dt='$log_date'
and  c3.dt='$log_date' and  c1.dt='$log_date'
and sku.id is not null;"
hive -e "$sql"

2)增加脚本执行权限

chmod 777 init_dwd.sh

3)执行脚本导入数据

init_dwd.sh 2021-07-10
init_dwd.sh 2021-07-11

4)查询导入数据

hive (gmall)>
select * from dwd_order_info where dt='2021-07-10' limit 1;
select * from dwd_order_info where dt='2021-07-11' limit 1;

4 DWS层–用户行为宽表

1)为什么要建宽表
需求目标,把每个用户单日的行为聚合起来组成一张多列宽表,以便之后关联用户维度信息后进行,不同角度的统计分析。

4.1 创建用户行为宽表

hive (gmall)>
drop table if exists dws_user_action;
create  external table dws_user_action
(   user_id         string      comment '用户 id',order_count     bigint      comment '下单次数 ',order_amount    decimal(16,2)  comment '下单金额 ',payment_count   bigint      comment '支付次数',payment_amount  decimal(16,2) comment '支付金额 '
) COMMENT '每日用户行为宽表'
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dws/dws_user_action/'
tblproperties ("parquet.compression"="snappy");

4.2 DWS层用户行为数据宽表导入脚本

1)在/workspace/hive/gmall/hive目录创建init_dws_user_wide.sh

vi init_dws_user_wide.sh

编写如下内容

#!/bin/bash# 定义变量方便修改
APP=gmall# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;thenlog_date=$1
else log_date=`date  -d "-1 day"  +%F`
fi sql="with
tmp_order as
(select user_id, sum(oc.total_amount) order_amount, count(*)  order_countfrom "$APP".dwd_order_info  ocwhere date_format(oc.create_time,'yyyy-MM-dd')='$log_date'group by user_id
)  ,
tmp_payment as
(select user_id, sum(pi.total_amount) payment_amount, count(*) payment_count from "$APP".dwd_payment_info pi where date_format(pi.payment_time,'yyyy-MM-dd')='$log_date'group by user_id
)
insert  overwrite table "$APP".dws_user_action partition(dt='$log_date')
select user_actions.user_id, sum(user_actions.order_count), sum(user_actions.order_amount),sum(user_actions.payment_count), sum(user_actions.payment_amount)
from
(select user_id, order_count,order_amount ,0 payment_count , 0 payment_amountfrom tmp_order union allselect user_id, 0,0, payment_count, payment_amountfrom tmp_payment) user_actions
group by user_id;"hive -e "$sql"

2)增加脚本执行权限

chmod 777 init_dws_user_wide.sh

3)执行脚本导入数据

init_dws_user_wide.sh 2021-07-10
init_dws_user_wide.sh 2021-07-11

4)查询导入数据

hive (gmall)>
select * from dws_user_action where dt='2021-07-10' limit 2;

五、GMV成交总额

5.1 ADS层

5.1.1 什么是GMV

5.12 建表语句

hive (gmall)>
drop table if exists ads_gmv_sum_day;
create table ads_gmv_sum_day( `dt` string COMMENT '统计日期',`gmv_count`  bigint COMMENT '当日gmv订单个数',`gmv_amount`  decimal(16,2) COMMENT '当日gmv订单总金额',`gmv_payment`  decimal(16,2) COMMENT '当日支付金额'
) COMMENT '每日活跃用户数量'
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ads/ads_gmv_sum_day/'
;

5.1.3数据导入

1)在/workspace/hive/gmall/hive目录创建init_ads_gmv.sh

vi init_ads_gmv.sh

编写如下内容

#!/bin/bash# 定义变量方便修改
APP=gmall# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;thenlog_date=$1
else log_date=`date  -d "-1 day"  +%F`
fi
sql="
insert into table "$APP".ads_gmv_sum_day
select
'$log_date' dt ,sum(order_count)  gmv_count ,sum(order_amount) gmv_amount ,sum(payment_amount) payment_amount
from dws_user_action
where dt ='$log_date'
group by dt
"

六、转化率

6.1 什么是转化率

6.2 ADS层之新增用户占日活跃用户比率

6.2.1 建表语句

hive (gmall)>drop table if exists ads_uv_count;
create table ads_uv_count(`dt` string COMMENT '统计日期',`day_count` bigint COMMENT '单日活跃用户数'
)COMMENT '每日活跃用户数量' row format delimited fields terminated by '\t'
location '/warehouse/gmall/ads/ads_uv_count/';drop table if exists ads_new_mid_count  ;
create table ads_new_mid_count  (`dt` string COMMENT '统计日期',`new_mid_count` bigint COMMENT '新增设备'
)COMMENT '每日活跃用户数量' row format delimited fields terminated by '\t'
location '/warehouse/gmall/ads/ads_new_mid_count/';
drop table if exists ads_user_convert_day;create   table ads_user_convert_day( `dt` string COMMENT '统计日期',`uv_m_count`  bigint COMMENT '当日活跃设备',`new_m_count`  bigint COMMENT '当日新增设备',`new_m_ratio`   decimal(10,2) COMMENT '当日新增占日活的比率'
) COMMENT '每日活跃用户数量'
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ads/ads_user_convert_day/'
;

6.2.2 数据导入

vi init_ads_user_convert_day.sh
#!/bin/bashAPP=gmallif [ $1 } ;thenlog_date=$1
else log_date=`date -d "-1 day" +%F`
fisql="
insert into "$APP".ads_uv_count values('$log_date',rand(1,100))
insert into "$APP".ads_new_mid_count values('$log_date',rand(1,100));insert into table "$APP".ads_user_convert_day
select '$log_date',sum( uc.dc) sum_dc,sum( uc.nmc) sum_nmc,cast(sum( uc.nmc)/sum( uc.dc)*100 as decimal(10,2))  new_m_ratio
from
(select day_count dc,0 nmcfrom ads_uv_count
where  dt='$log_date' union allselect  0 dc,new_mid_count nmcfrom ads_new_mid_count  where create_date='$log_date'
)uc;
"

执行脚本

七、品牌复购率

需求:以月为单位,购买2次以上商品的用户

7.1 复购率计算分析

7.2 DWS层

7.2.1 用户购买商品明细表(宽表)

建表语句

hive (gmall)>
drop table if exists  dws_sale_detail_daycount;
create external table  dws_sale_detail_daycount
(   user_id   string  comment '用户 id',sku_id    string comment '商品 Id',user_gender  string comment '用户性别',user_age string  comment '用户年龄',user_level string comment '用户等级',order_price decimal(10,2) comment '订单价格',sku_name string   comment '商品名称',sku_tm_id string   comment '品牌id',sku_category3_id string comment '商品三级品类id',sku_category2_id string comment '商品二级品类id',sku_category1_id string comment '商品一级品类id',sku_category3_name string comment '商品三级品类名称',sku_category2_name string comment '商品二级品类名称',sku_category1_name string comment '商品一级品类名称',spu_id  string comment '商品 spu',sku_num  int comment '购买个数',order_count string comment '当日下单单数',order_amount string comment '当日下单金额'
) COMMENT '用户购买商品明细表'
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dws/dws_user_sale_detail_daycount/'
tblproperties ("parquet.compression"="snappy");

7.2.2 数据导入

vi init_dws_sale_detail_daycount.sh
#!/bin/bash# 定义变量方便修改
APP=gmall# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;thenlog_date=$1
else log_date=`date  -d "-1 day"  +%F`
fi sql="set hive.exec.dynamic.partition.mode=nonstrict;with
tmp_detail as
(select user_id,sku_id, sum(sku_num) sku_num ,   count(*) order_count , sum(od.order_price*sku_num)  order_amount from "$APP".ods_order_detail odwhere od.dt='$log_date' and user_id is not nullgroup by user_id, sku_id
)
insert overwrite table  "$APP".dws_sale_detail_daycount partition(dt='$log_date')
select tmp_detail.user_id,tmp_detail.sku_id,u.gender,months_between('$log_date', u.birthday)/12  age, u.user_level,price,sku_name,tm_id,category3_id ,  category2_id ,  category1_id ,  category3_name ,  category2_name ,  category1_name ,  spu_id,tmp_detail.sku_num,tmp_detail.order_count,tmp_detail.order_amount
from tmp_detail
left join "$APP".dwd_user_info u
on u.id=tmp_detail.user_id  and u.dt='$log_date'
left join "$APP".dwd_sku_info s on tmp_detail.sku_id =s.id  and s.dt='$log_date';"
hive -e "$sql"

执行脚本

7.3 ADS层

7.3.1 建表语句

hive (gmall)>
drop  table ads_sale_tm_category1_stat_mn;
create  table ads_sale_tm_category1_stat_mn
(   tm_id string comment '品牌id ' ,category1_id string comment '1级品类id ',category1_name string comment '1级品类名称 ',buycount   bigint comment  '购买人数',buy_twice_last bigint  comment '两次以上购买人数',buy_twice_last_ratio decimal(10,2)  comment  '单次复购率', buy_3times_last   bigint comment   '三次以上购买人数',buy_3times_last_ratio decimal(10,2)  comment  '多次复购率' ,stat_mn string comment '统计月份',stat_date string comment '统计日期'
)   COMMENT '复购率统计'
row format delimited  fields terminated by '\t'
location '/warehouse/gmall/ads/ads_sale_tm_category1_stat_mn/'
;

7.3.2 数据导入

vi ads_sale_tm_category1_stat_mn.sh
#!/bin/bash# 定义变量方便修改
APP=gmall# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;thenlog_date=$1
else log_date=`date  -d "-1 day"  +%F`
fi sql="set hive.exec.dynamic.partition.mode=nonstrict;insert into table "$APP".ads_sale_tm_category1_stat_mn
select   mn.sku_tm_id,mn.sku_category1_id,mn.sku_category1_name,sum(if(mn.order_count>=1,1,0)) buycount,sum(if(mn.order_count>=2,1,0)) buyTwiceLast,sum(if(mn.order_count>=2,1,0))/sum( if(mn.order_count>=1,1,0)) buyTwiceLastRatio,sum(if(mn.order_count>3,1,0))  buy3timeLast  ,sum(if(mn.order_count>=3,1,0))/sum( if(mn.order_count>=1,1,0)) buy3timeLastRatio ,date_format('$log_date' ,'yyyy-MM') stat_mn,'$log_date' stat_date
from
(     select od.sku_tm_id, od.sku_category1_id,od.sku_category1_name,  user_id , sum(order_count) order_countfrom  "$APP".dws_sale_detail_daycount  od where date_format(dt,'yyyy-MM')<=date_format('$log_date' ,'yyyy-MM')group by od.sku_tm_id, od.sku_category1_id, user_id, od.sku_category1_name
) mn
group by mn.sku_tm_id, mn.sku_category1_id, mn.sku_category1_name;"
hive -e "$sql"

执行脚本

7.4 品牌复购率结果输出到MySQL

1)在MySQL中创建ads_sale_tm_category1_stat_mn表

create  table ads_sale_tm_category1_stat_mn
(   tm_id varchar(200) comment '品牌id ' ,category1_id varchar(200) comment '1级品类id ',category1_name varchar(200) comment '1级品类名称 ',buycount   varchar(200) comment  '购买人数',buy_twice_last varchar(200) comment '两次以上购买人数',buy_twice_last_ratio varchar(200) comment  '单次复购率', buy_3times_last   varchar(200) comment   '三次以上购买人数',buy_3times_last_ratio varchar(200)  comment  '多次复购率' ,stat_mn varchar(200) comment '统计月份',stat_date varchar(200) comment '统计日期'
)

2)编写Sqoop导出脚本

vim gmall_export.sh
#!/bin/bashdb_name=gmallexport_data() {/opt/module/sqoop/bin/sqoop export \
--connect "jdbc:mysql://hostname:3306/${db_name}?useUnicode=true&characterEncoding=utf-8"  \
--username root \
--password 000000 \
--table $1 \
--num-mappers 1 \
--export-dir /warehouse/$db_name/ads/$1 \
--input-fields-terminated-by "\t"  \
--update-key "tm_id,category1_id,stat_mn,stat_date" \
--update-mode allowinsert \
--input-null-string '\\N'    \
--input-null-non-string '\\N'
}case $1 in"ads_sale_tm_category1_stat_mn")export_data "ads_sale_tm_category1_stat_mn"
;;"all")export_data "ads_sale_tm_category1_stat_mn"
;;
esac

3)执行Sqoop导出脚本
4)在MySQL中查看结果

八、订单拉链表

8.1 什么是订单拉链表

8.2 为什么要做拉链表

8.3 拉链表形成过程

8.4拉链表制作过程图

8.5 拉链表制作过程

8.5.1 初始化拉链表,首次独立运行

1)生成10条原始订单数据

CALL init_data('2021-07-12',10,5,10,TRUE);gmall_import.sh 2021-07-12init_ods.sh 2021-07-12
init_dwd.sh 2021-07-12

2)建立拉链表

hive (gmall)>
drop table if exists dwd_order_info_his;
create table dwd_order_info_his( `id` string COMMENT '订单编号',`total_amount` decimal(10,2) COMMENT '订单金额', `order_status` string COMMENT '订单状态', `user_id` string COMMENT '用户id' ,`payment_way` string COMMENT '支付方式',  `out_trade_no` string COMMENT '支付流水号',  `create_time` string COMMENT '创建时间',  `operate_time` string COMMENT '操作时间' ,`start_date`  string COMMENT '有效开始日期',`end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链表'
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_info_his/'
tblproperties ("parquet.compression"="snappy");

3)初始化拉链表

hive (gmall)>
insert overwrite table dwd_order_info_his
select id,total_amount,order_status,user_id,payment_way,out_trade_no,create_time,operate_time,'2021-07-12','9999-99-99'
from ods_order_info oi
where oi.dt='2021-07-12';

4)查询拉链表中数据

8.5.2 先制作当日变动(包括新增,修改)每日执行

1)如何获得每日变动表

(1)最好表内有创建时间和变动时间(Lucky!)

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

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

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

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

(1)2021-07-13日新增2条订单数据

CALL init_data('2021-07-13',2,5,10,TRUE);

2)通过Sqoop把2021-07-13日所有数据导入

gmall_import.sh 2021-07-13init_ods.sh 2021-07-13
init_dwd.sh 2021-07-13

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

1)建立临时表

hive (gmall)>
drop table if exists dwd_order_info_his_tmp;
create external table dwd_order_info_his_tmp( `id` string COMMENT '订单编号',`total_amount` decimal(10,2) COMMENT '订单金额', `order_status` string COMMENT '订单状态', `user_id` string COMMENT '用户id' ,`payment_way` string COMMENT '支付方式',  `out_trade_no` string COMMENT '支付流水号',  `create_time` string COMMENT '创建时间',  `operate_time` string COMMENT '操作时间',`start_date`  string COMMENT '有效开始日期',`end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_info_his_tmp/'
tblproperties ("parquet.compression"="snappy");

2)导入脚本

hive (gmall)>
insert overwrite table dwd_order_info_his_tmp
select * from
(
select
id,total_amount   , order_status , user_id  ,payment_way  ,  out_trade_no,  create_time ,  operate_time ,'2021-07-13' start_date,'9999-99-99' end_date
from dwd_order_info where dt='2021-07-13'union all
select oh.id,oh.total_amount   , oh.order_status , oh.user_id  ,oh.payment_way  ,  oh.out_trade_no,  oh.create_time ,  oh.operate_time ,oh.start_date,if(oi.id is null ,oh.end_date, date_add(oi.dt,-1)) end_date
from dwd_order_info_his oh left join (
select
*
from dwd_order_info
where  dt='2021-07-13'
) oion oh.id=oi.id and oh.end_date='9999-99-99'
)his
order by his.id, start_date;

8.5.4 把临时表覆盖给拉链表

1)导入数据

hive (gmall)>
insert overwrite table  dwd_order_info_his
select * from  dwd_order_info_his_tmp;

2)查询导入数据

九、OLAP分析工具之Presto

9.1 Presto Server安装

参考:https://editor.csdn.net/md/?articleId=119709295
1)后台启动presto

bin/launcher start

9.2 Presto命令行

启动prestocli

./prestocli --server hostname:8881 --catalog hive --schema default

Presto命令行操作
Presto的命令行操作,相当于hive命令行操作,不过没有use命令。每个表必须要加上schema。

9.3 Presto可视化Client安装

yanagishima安装参考:https://editor.csdn.net/md/?articleId=119713856
启动yanagishima

nohup bin/yanagishima-start.sh >y.log 2>&1 &

启动web页面
http://hostnamr:7080

9.4 Presto可视化操作

十、Azkaban调度器

Azkaban安装参考:

10.1 复购率指标的产生的全调度流程

1)生成数据

CALL init_data('2021-07-14',300,200,300,FALSE);

2)编写Azkaban程序运行job,
(1) import文件

type=command
do_date=${dt}
command=/workspace/hive/gmall/sqoop/gmall_import.sh all ${do_date}

(2)ods文件

type=command
do_date=${dt}
dependencies=import
command=/workspace/hive/gmall/hive/init_ods.sh ${do_date}

(3)dwd文件

type=command
do_date=${dt}
dependencies=ods
command=/workspace/hive/gmall/hive/init_dwd.sh ${do_date}

(4)dws文件

type=command
do_date=${dt}dependencies=dwd
command=/workspace/hive/gmall/hive/init_dws_user_wide.sh ${do_date}

(5)ads文件

type=command
do_date=${dt}
dependencies=dws
command=/workspace/hive/gmall/hive/init_dws_sale_detail_daycount.sh ${do_date}

6)export文件

type=command
do_date=${dt}
dependencies=ads
command=/workspace/hive/gmall/sqoop/gmall_export.sh  ${do_date}

(7)将以上6个文件压缩成gmall-job.zip文件

3)创建Azkaban工程,并上传gmall-job.zip文件。

参考文章:https://blog.csdn.net/qq_31784189/article/details/105125636?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase

大数据项目--电商业务数据仓库相关推荐

  1. 视频教程-全新大数据企业电商数据仓库项目实战教程-大数据

    全新大数据企业电商数据仓库项目实战教程 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业.拥有丰 ...

  2. 大数据之电商分析系统(一)

    大数据之电商分析系统(一) 一:项目介绍 ​ 本项目来源于企业级电商网站的大数据统计分析平台, 该平台以 Spark 框架为核心, 对电商网站的日志进行离线和实时分析.该大数据分析平台对电商网站的各种 ...

  3. 金融科技大数据产品推荐:蓝金灵—基于大数据的电商企业供应链金融服务平台

    官网 | www.datayuan.cn 微信公众号ID | datayuancn 本产品为数据猿推出的"金融科技价值-数据驱动金融商业裂变"大型主题策划活动第一部分的文章/案例/ ...

  4. 大数据之电商推荐系统

    #大数据之电商推荐系统# 项目系统架构 数据整理 商品数据 商品ID 商品名称 商品种类 商品图片URL 商品标签 productId name categories imageUrl tags 评分 ...

  5. 电商数仓描述_大数据企业级电商数据仓库架构设计和实现(技术点与企业接轨)...

    课程咨询和资料获取请加老师QQ  1011800132 该项目以国内电商巨头实际业务应用场景为依托,紧跟大数据主流需求,对电商数仓的常见实战指标以及难点实战指标进行了详尽讲解,让你迅速成长,获取最前沿 ...

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

    这个项目实在数据采集基础使用的,需要提前复习之前学的东西,否则的话就是很难继续学习.详见博客数据项目一 ---数据采集项目.大数据项目 --- 数据采集项目_YllasdW的博客-CSDN博客大数据第 ...

  7. 腾讯防刷负责人:基于用户画像大数据的电商防刷架构

    本文由颜国平在高可用架构群所做的分享整理,转载请注明高可用架构公众号ArchNotes. 颜国平,腾讯云-天御系统研发负责人. 一直负责腾讯自有验证码.业务安全.防刷.账号安全等研发工作. 内部支持的 ...

  8. 【大数据实战电商推荐系统】

    文章目录 第1章 项目体系框架设计 第2章 工具环境搭建 第3章 项目创建并初始化业务数据 3.1 IDEA创建Maven项目(略) 3.2 数据加载准备(说明书) 3.3 数据初始化到MongoDB ...

  9. 基于用户画像大数据的电商防刷架构

    http://blog.csdn.net/tengxy_cloud/article/details/52576675 一.背景介绍 最近1~2年电商行业飞速发展,各种创业公司犹如雨后春笋大量涌现,商家 ...

最新文章

  1. 基于libmad库的MP3解码简析
  2. 一文读懂PyTorch张量基础(附代码)
  3. composer安装其实可以很简单 两行命令就解决了
  4. 详解Xcode 4发布程序图文并茂教程
  5. android web3j 代币查询_Android通过web3j以太坊智能合约交互
  6. 【APICloud系列|19】上架APPStore需要准备哪些材料?
  7. 低级程序员才喜欢写注释!
  8. 网站站长综合seo在线查询工具源码
  9. 程序员如何 10 分钟用 Python 画出蒙娜丽莎?
  10. 使用 .NET 平台,如何玩转 Universal Windows 应用? 1
  11. 501.二叉搜索树中的众数
  12. Excel 有哪些可能需要熟练掌握而很多人不会的技能
  13. 人工智能导论期末复习重点
  14. 使用IDEA编写Java程序时遇到的小提醒Common part can be extracted from ‘if‘
  15. 闲聊注册中心——ZK、Eureka、Sofa-Registry
  16. 误删通话记录?这几个方法能恢复
  17. 自动驾驶开发中的地图
  18. python现成项目_搭建python项目
  19. [Linux](小白须知)超级用户、普通用户、系统管理员怎么区分
  20. 增强型MOS管工作相关问题

热门文章

  1. Tessent专栏第4篇:TessentMemoryBIST用户手册第二章上
  2. 空军一号html,青花瓷 x 空军一号,你不知道的30双AF1
  3. 图片怎么去底色变透明?怎么把图片变透明背景?
  4. 编写shell脚本实现自动化搭建安装LNMP平台全过程配置详解
  5. 理工科学子,从事工程仿真所需的知识结构和学习方法
  6. sdk_int值对照表
  7. 游戏运营数据报告写法思路
  8. Sniffer4D灵嗅
  9. CSAPP大作业论文 程序人生
  10. mysql 查询分析工具下载_SQL分析工具下载-SQL查询工具(DB Solo)下载v5.2.5官方版-西西软件下载...