[hive]数仓分层|用户纬度拉链表|维度建模

news2024/11/17 21:42:46

https://www.modb.pro/404?redirect=%2Fdb%2F241289

一、数仓分层

1、ODS层:原始数据层

ODS(O=original D=data S=store)

1)设计要点

存储来自多个业务系统、前端埋点、爬虫获取的一系列数据源的数据。

我们要做三件事:

【1】保持数据原貌不做任何修改,保留历史数据,起到数据备份的作用。

【2】使用lzo压缩。100G的数据压缩之后大概为20G。

【3】创建分区表,防止后续的全表扫描,一般按天存储。

2)ODS层数据组成

【1】前端埋点日志:由kafka或者flume采集到HDFS上

flume采集的语句[flume]参数设置_胖胖学编程的博客-CSDN博客

【2】由前端业务数据库用sqoop采集到HDFS上

3)前端埋点日志的处理

前端埋点日志以JSON格式形式存在

建表语句

createexternaltable ods_flow_ph
(
    line string
)
partitioned by (dt string)
Stored as  
inputformat 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
outputformat 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
;

将flume落盘的数据建立lzo索引,否则无法分片

hadoop jar /opt/module/hadoop-3.1.4/share/hadoop/common/hadoop-lzo-0.4.20.jar \
com.hadoop.compression.lzo.DistributedLzoIndexer \
-Dmapreduce.job.queuename=hive \
/user/hive/warehouse/ods.db/ods_flow_ph/dt=2022-11-11

加载建立好索引的数据

load data inpath '/user/hive/warehouse/ods.db/ods_flow_ph/dt=2022-11-11'intotable ods_flow_ph partition (dt='2022-11-11');

4)MySQL数据库的处理

mysql数据库的表通过sqoop采集到HDFS,使用\t作为分隔符,那ods层的表也要使用\t作为分割符;

5)同步策略

(1)每日增量同步:流量表(ods_flow_ph)

也是埋点表,小时级增量表,所有的埋点数据都汇总在这一张表中。

包括前后端埋点和后端埋点

【1】前端埋点与后端埋点:

前端埋点:不需要网络的,在自己手机app/浏览器/小程序里就能产生的用户行为数据,这些数据会定期上报到服务器。 后端的数据:需要和MySQL交互的数据,例如用户注册的时候,要把用户名密码之类的存道MySQL。

数据时间漂移:用户手机中存的前端的数据会累积到一定条数再发送到服务器,例如80条,假如用户1-1号存了40条就关掉了app,1-2号打开了app,这40条的数据就会变成1-2的了。

举例:用户关注了另一个用户是后端埋点用户关注列表+1,用户上传了一个课程视频是后端埋点,因为要把视频上传到服务器。

既然后端的数据都写入到服务器了,那为什么还需要后端埋点呢?

比如一个用户关注了另一个用户,又取消关注了,这样的话后端的表里就没有这条记录了,但是可以从埋点里面查看到:关注了,并且取消关注了这个行为。这个行为在埋点表设计的时候,还得带用户id,关注了谁的id,这两个字段。

【2】导入方式

如果是用的apache hadoop。用Nginx负载均衡,把数据均匀的发送到日志服务器中。就直接用flume拉取数据,taildir source memory channel hdfs sink。

要是用阿里的dataworks:包括调度+数据集成(从MySQL啥的导数据)+MaxCompute(类似hive,可以写sql) 注:一般用阿里的服务的话还用quickBI做报表展示。就是后端和前端将数据写入到kafka中,然后从kafka中每小时进行数据同步。

(2)每日全量同步:用户表、订单表、看课表、课程表、章节表、教师表、互动表、卡片表

用户维度表:维度表。来自于后端,里面包含了用户的基本信息,例如用户的性别,年龄,生日,星座,职业等等。

课程维度表:记录课程属性信息的维度表。例如课程id 课程名称 课程url 教师id等等。

订单表:由学员购买课程,下单产生记录。

看课表:由学生看课产生的记录,细分为两张表:直播看课记录表、录播看课记录表。

章节表:课程的每一章节信息,例如课程id 课程名称 章节id 章节名称 等。

教师表:存储教师信息

互动表:用户的评论、关注、分享行为

卡片表:课程页面曝光与点击表,由组内其他成员使用spark开发

(3)特殊:一次性拉取,不建分区表(DIM层的父数据)

例如地区表,单位表

2、DIM

dim=dimension。存储为Parquet格式。

1)同步策略

全量同步:课程维度表。首日和每日都是全量先导入到ODS再导入到DIM层。

拉链表:用户维度表

特殊:单位表、地区(自己处理)

2)拉链表

(1)什么是拉链表

用于存储变化,但变化的频率较慢的数据。如果用全量存储,会存储大量重复的数据,因此用拉链表。

(2)每条数据的意义

该条数据的有效时间。

(3)制造拉链表

【1】建表语句

create table dim_user_info(
id string,
user_name string --用户名称,
name string --真实姓名,
phone_num string,
gerder string --性别,
email string,
create_time string --创建时间,
operate_time string --操作时间,
start_date string --开始日期(拉链表特有),
end_date string --结束日期(拉链表特有)
)
partitioned by(dt string)
stored as parquet
table properties("parquet.compression"="lzo")

【2】分区规划

【3】首日装载

要进行初始化,ods层该表第一天从MySQL拉取的所有数据放到9999-99-99分区

insert overwrite table dim.dim_user_info partition(dt='9999-99-99')
select
id,
user_name,
name,
phone_num,
gerder,
email,
create_time,
operate_time,
'2022-19-01' start_date,
'9999-99-99' end_date
from 
ods.ods_user_info
where dt='2022-10-01'

【4】每日装载

a)将最新的数据装载到9999-99-99分区

如果new为null(没有变化),则取old

如果new不为null(今天发生了新增及变化),则取new

select
if(new.id is not null,new.id,old.id) id,
if(new.user_name is not null,new.user_name,old.user_name) user_name,
if(new.name is not null,new.name,old.name) name,
if(new.phone_num is not null,new.phone_num,old.phone_num) num,
if(new.gerder is not null,new.gerder,old.gerder) gerder,
if(new.email is not null,new.email,old.email) nemail,
if(new.create_time is not null,new.create_time,old.create_time) create_time ,
if(new.operate_time is not null,new.operate_time,old.operate_time) operate_time,
if(new.start_date is not null,new.start_date,old.start_date) start_date,
if(new.end_date is not null,new.end_date,old.end_date) end_date
(
    select
    id,
    user_name,
    name,
    phone_num,
    gerder,
    email,
    create_time,
    operate_time,
    '2022-19-01' start_date,
    '9999-99-99' end_date
    from 
    dim.dim_user_info
    where dt='9999-99-99'
)ods
full join
(
    select
    id,
    user_name,
    name,
    phone_num,
    gerder,
    email,
    create_time,
    operate_time,
    '2022-10-01' start_date,
    '9999-99-99' end_date --新增及变化的数据都是最新数据
    from 
    ods.ods_user_info --ods_user_info表是每日增量导入的
    where dt='2022-10-01' --新增及变化的数据
    )new
on ods.id=new.id

b)将过期数据装载到前一天的分区(注意日期之间没有重合)

new和old都有的数据取old

select
old.id id,
old.user_name user_name,
old.name name,
old.phone_num num,
old.gerder gerder,
old.email nemail,
old.create_time create_time ,
old.operate_time operate_time,
old.start_date start_date,
old.end_date end_date
(
    select
    id,
    user_name,
    name,
    phone_num,
    gerder,
    email,
    create_time,
    operate_time,
    '2022-19-01' start_date,
    '9999-99-99' end_date
    from 
    dim.dim_user_info
    where dt='9999-99-99'
)ods
full join
(
    select
    id,
    user_name,
    name,
    phone_num,
    gerder,
    email,
    create_time,
    operate_time,
    '2022-10-01' start_date,
    '9999-99-99' end_date --新增及变化的数据都是最新数据
    from 
    ods.ods_user_info --ods_user_info表是每日增量导入的
    where dt='2022-10-01' --新增及变化的数据
    )new
on ods.id=new.id
where new.id is not null and old.id is not null
;

(4)对拉链表进行查询

【1】获取在某天有效的所有用户的数据

--获取2019-01-01有效的所有历史数据
select * from user_info where start_date<='2019-01-01' and end_date>='2019-01-01';

【2】获取目前所有用户的最近数据

select * from user_info where end_date>='9999-99-99';

3、DWD层

dwd=data warehouse detail

1)说明

dwd层是对事实表的处理,代表的是业务的最小粒度层,任何数据的记录都可以从这一层获取,为后续的dws和dwt层做准备。

dwd层是站在选择好事实表的基础上,对维度建模的视角。

2)对埋点数据进行处理

将流量表(ods_flow_ph)表唯一的字段line这个json串进行解析,解析成一个字段一个字段的。

3)对业务数据进行处理

【1】周期快照事实表

除了流量表以外的表都是从MySQL导入进来的。

103-尚硅谷-数仓搭建-DWD层优惠券领用事实表_哔哩哔哩_bilibili

一个知识点:累计快照事实表(没看完)
如:优惠券领用,这种发生周期变化的场景
createtable dwd_coupun_use(
coupun_id string, --优惠券id
user_id string, --用户id
coupun_status string, --优惠券状态
using_time string, --使用时间(下单)
used_time string, --使用时间(支付)
expire_time  string --过期时间
)
partitioned by(dt string)
;

4、dim和dwd

DIM和DWD采用维度建模,一般采用星型模型,呈现状态一般为星座模型。详情见维度建模的步骤。

5、dws、dwt、ads

dws= data warehouse service

dwt=data warehosue topic

ads=application data store

dws、dwt、ads都是以需求为驱动的,和纬度建模已经没有关系了。

dws、dwt:统称为宽表层,这两层的设计思想大致相同,通过以下案例进行说明:

1)问题引出

两个需求,统计每个省份订单的个数、统计内个省份订单的总金额

2)处理办法

都是将省份和订单表进行join,group by省份,然后计算,同样的数据被计算了两次,实际上类似的场景还有很多,那怎么设计才能避免重复计算呢?针对上述场景可以设计一张地区表,其主键为地区ID,字段为:下单次数,下单金额,支付次数,支付金额等,上述所有指标统一进行计算,并将结果保存在该宽表中,这样就能有效避免数据的重复计算。

3)需要那些宽表(主题表):以维度为基准

4)DWS和DWT层的区别:

DWS层存放所有当天的汇总行为,例如每个地区当天下单次数,下单金额等,dwt层存放的是所有主题对象的累计行为,例如每个地区最近7天(15天、30天、60天)的下单次数,下单金额等。

5)ads层:存储各个报表需要的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一阶高通滤波器学习

导读&#xff1a;本期文章主要介绍一阶高通滤波器。一阶高通滤波器与一阶低通滤波器很相似&#xff0c;都是利用电容阻低频信号通高频信号&#xff0c;电感阻高频信号通低频信号的特点。一、一阶高通滤波器介绍滤波器是作为一种选频装置&#xff0c;是信号处理中的一个重要的概…

Linux(二)进程概念

目录 一、冯诺依曼体系结构 二、操作系统 三、进程概念 1、程序与进程的区别&#xff1a; 2、cpu分时机制 3、pcb——进程控制块 4、进程是什么&#xff1f; 四、进程状态 1、linux状态 2、僵尸态 pid_t fork(void)&#xff1a; fork创建进程之后&#xff0c;父子进…

vector以及list

之前已经学习过了string类&#xff0c;接下来介绍c中的另外两个类—— vector和list&#xff1b; vector 之前介绍的string类是c所特定的字符数组&#xff1b; 而vector可以看做是string类的扩展&#xff0c;因为它是一个模板类&#xff1b; 它可以作为任何类型的数组&#x…

小侃设计模式(廿二)-访问者模式

1.概述 访问者模式&#xff08;Visitor Pattern&#xff09;指的是在类的内部结构不变的情况下&#xff0c;不同的访问者访问这个对象都会呈现出不同的处理方式。它的主要作用时将数据结构与数据操作分离&#xff0c;将不同的算法与其所作用的对象进行分离。本文将详述访问者模…

DW动手学数据分析Task2:数据清洗及特征处理

文章目录一 数据清洗1 缺失值观察与处理1.1 缺失值观察1.2 缺失值处理2 重复值观察与处理二 特征处理1 分箱&#xff08;离散化&#xff09;处理2 对文本变量进行转换3 从纯文本Name特征里提取出Titles的特征3 参考文章一 数据清洗 数据清洗&#xff1a;我们拿到的数据通常是不…

树的知识概括锦囊(一)

作者&#xff1a;爱塔居 专栏&#xff1a;数据结构 作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 一、树形结构 二、树的基础知识 三、二叉树 3.1 概念 3.2 特殊的二叉树 ​编辑 3.3 二叉树的性质 四、习题挑战 一、树形结…

手把手教你学51单片机-如何学习单片机

大多数大学生之所以最后变的平庸,不是因为脑子多么笨,也不是全怪自己贪玩不上进,只是没有一个好的领路人,许多学校可能挂着导师的名头,但是多数是挂羊头卖狗肉或者是干脆不管。最后等大学生毕业之后,那些所谓的老师就会说学生很差或者学习很差,反正就是跟自己没啥关系。…

OSPF综合实验(华为)

题目&#xff1a; 思路&#xff1a; 首先配置每个区域的路由和环回地址&#xff0c;其次&#xff0c;根据题目要求打通每个网络的连接&#xff0c;区域0用MGRE打通网络&#xff0c;区域4需要重发布&#xff0c;其次再考虑优化的问题。ip地址的规划是为了更好的路由汇总&#x…

《 Unity Shader 入门精要》第5章 开始 Unity Shader 学习之旅

第5章 开始 Unity Shader 学习之旅 5.2 一个最简单的顶点/片元着色器 顶点/片元着色器的基本结构 // Upgrade NOTE: replaced mul(UNITY_MATRIX_MVP,*) with UnityObjectToClipPos(*)// 定义 shader 的名字 Shader "Chapter 5/Simple Shader" {SubShader{Pass {//…

自动驾驶控制算法之车辆横向控制(project)

本文为深蓝学院-自动驾驶控制与规划-第三章作业 目录 1 projection introduction 2 思路提示 2.1 ComputeControlCmd 2.2 ComputeLateralErrors 3 Corer Case 3.1 Low speed operation 3.2 Extra damping on heading 3.3 Steer into constant radius curve 4 ROSLGSV…

FFmpeg-4.2.4的filter: drawbox源码分析

1. vf_drawbox.c功能 有两个功能 ,添加方框,和添加网格; 1.1 添加方框效果 1.2 添加网格效果

c++数据结构-树(详细总结附代码,一看就懂)

树的定义一棵树是由n&#xff08;n>0&#xff09;个元素组成的有限集合&#xff0c;其中&#xff1a;&#xff08;1&#xff09;每个元素称为结点&#xff08;node&#xff09;&#xff08;2&#xff09;有一个特定的结点&#xff0c;称为根结点或树根&#xff08;root&…

上海亚商投顾:双创指数低开高走,数字经济继续活跃

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪三大指数今日低开高走&#xff0c;创业板指午后涨超1%&#xff0c;科创50指数涨超1.6%。数字经济概念继续爆发&#…

算法基础(一):时间复杂度和空间复杂度

算法基础&#xff08;一&#xff09;&#xff1a;时间复杂度和空间复杂度时间复杂度 O(1)O(1)O(1) O(N)O(N)O(N) O(logN)O(log N)O(logN) O(MN)O(MN)O(MN) O(NlogN)O(Nlog N)O(NlogN)、O(MlogN)O(Mlog N)O(MlogN) O(N2)O(N^2)O(N2)空间复杂度一些算法基础知识点和leetcode题解&…

【网络通信】【电信运营商实战工程师】思科设备篇-思科设备企业网实战

电信运营商实战工程师系列文章. 思科设备篇-思科设备企业网实战. 文章目录1. 思科设备基本开局配置2. ARP协议、交换机工作原理及广播风暴问题3. 思科设备 VLAN 及单臂路由实战4. 思科三层交换机实现 VLAN 间路由实战5. 思科设备静态默认及浮动路由实战6. 思科设备NAT实战全集1…

YOLO_V8训练自己的数据集

YOLO_V8在2023年开年横空出世&#xff0c;在春节前还得卷一下。由于YOLO_V8和YOLO_V5是同一个作者&#xff0c;所以很多操作都是一样的&#xff0c;下面主要描述一下如何用自己的数据集进行训练和测试&#xff08;非命令行的方式&#xff09;。1、训练数据和模型的目录结构这里…

设计模式学习(九):Abstract Factory抽象工厂模式

目录 一、什么是Abstract Factory模式 二、Abstract Factory示例代码 2.1 类之间的关系 2.2 抽象的零件:ltem类 2.3 抽象的零件:Link类 2.4 抽象的零件:Tray类 2.5 抽象的产品: Page类 2.6 抽象的工厂:Factory类 2.7 使用工厂将零件组装称为产品:Main类 2.8 具体的工厂…

linux三剑客之AWK

目录 AWK是什么 AWK基本结构 a.txt的文本实例 AWK内置变量 a.txt的文本实例 AWK自定义变量 a.txt的文本实例 AWK内置函数 a.txt的文本实例 awk高级输出 a.txt的文本实例 排序输出 a.txt的文本实例 条件选择输出 a.txt的文本实例 控制语句 a.txt的文本实例 AWK是什…

Java SE 继承和多态

继承和多态 1. 继承 1.1 为什么需要继承 Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是 现实世界错综复杂&#xff0c;事物之间可能会存在一些关联&#xff0c;那在设计程序是就需…

Elasticsearch7.8.0版本高级查询—— 指定查询字段查询文档

目录一、初始化文档数据二、指定查询字段查询文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; {"name":"张三","…