[hive]维度模型分类:星型模型,雪花模型,星座模型|范式|纬度建模|数仓分层

news2024/11/26 4:38:55

数仓(十八)数仓建模以及分层总结(ODS、DIM、DWD、DWS、DWT、ADS层) - 墨天轮

一、维度模型分类:星型模型,雪花模型,星座模型

1、星型模型

星型模型中只有一张事实表,以及0张或多张维度表,事实与纬度表通过主键外键相关联,维度之间不存在关联关系,当所有纬度都关联到事实表时,整个图形非常像一种星型的结构,所以称之为“星型模型”。

注:事实表中只存外键和度量值。

2、雪花模型

当一个或多个纬度表没有直接连接到事实表,而是通过其他维度表连接到事实表时,其图解就像多个雪花连接在一起,故称雪花模型。雪花模型是对星型模型的扩展,它对星型模型的维度进一步层次化。

优点是避免了数据冗余。

缺点是增加了join,导致效率低。

3、星座模型

星座模型也是星型模型的扩展,区别是星座模型中存在多张事实表,不同的事实表之间共享维度表信息。日常开发用的就是星座模型。

 二、范式

范式:在进行关系建模时,需要遵循的规则。

范式的作用:降低数据的冗余性,减少存储空间,保持数据一致性。

1、函数依赖:

完全函数依赖,部分函数依赖,传递函数依赖。

1)完全函数依赖

z=f(x,y)有了x,y才能计算出z,所以z完全函数依赖于x,y。比如通过(学号,课程)推出分数,但是单纯用学号推断不出来分数,那么就可以说分数全完依赖于(学号,课程)。

2)部分函数依赖

z=f(x,y)当给定x,y则能计算出z,当给x,y,n时,也能计算出z,此时z部分函数依赖于z,y,n。比如通过(学号,课程)推出姓名,因为可以直接通过学号退出姓名,所以:姓名部分依赖于(学号,课程)。

3)传递函数依赖

y=f(x),z=g(y),依赖x可以得到y,从而得到z,z传递依赖于x。比如:学号推出系名,系名退出系主任,系主任传递依赖于学号。

2、第一范式

字段不可分割。

 商品字段中"5台电脑"可以切割成"5台"+"电脑",改为

3、第二范式

满足第一范式,且不能存在非主键字段部分函数依赖于主键字段。

主键为:"学号"+"课名"。"分数”完全依赖于(学号,课名),但是姓名并不完全依赖于(学号,课名),姓名只依赖于学号。

4、第三范式

满足第一二范式,且不能存在非主键字段传递函数依赖于主键字段。

 主键:学号。学号->系名->系主任

上面表需要再次拆解:

三、纬度建模

纬度建模步骤:选择业务过程声明粒度、确认纬度、确认事实

1、选择业务过程

整个业务流程中选取我们需要建模的业务,根据公司业务提供的需求及日后的易扩展性等进行选择业务。

这里我们选择了几个业务过程是:支付、订单、加购物车、优惠券领用、收藏、评论、退款等。

2、声明粒度

总体采用最小粒度规则,不做任何聚合操作。而在实际公司应用中,对于有明确需求的数据,我们建立针对需求上卷汇总粒度,对需求不明朗的数据我们建立原子粒度。

对于支付业务,声明粒度:支付业务中(事实表)中一行数据表示的是一条支付记录。

对于订单业务,声明粒度:订单业务中一行数据表示的是一个订单中的一个商品项。

3、确认纬度

这里我们确认维度的原则是:

1)根据目前业务需求的相关描述性标识

2)描述业务相关的维度指标

3)后续需要相关维度指标

4、确认事实

确认业务中的度量值(如次数、个数、件数、金额等其他可以进行累加的值)例如订单金额、下单次数。简单理解为:我们站在事实表的角度上,分别对每个事实表进行维度关联操作,建立关联关系。

四、数仓分层

1、ODS层:原始数据层

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

1)设计要点

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

我们要做三件事:

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

【2】使用lzo压缩。

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

2)ODS层数据组成

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

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

3)前端埋点日志的处理

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

建表语句

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

将kafka落盘的数据建立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 \
/warehouse/gmail/ods/ods_log/dt=2021-05-01

加载建立好所以的数据

load data inpath '/origin_data/gmall/log/topic_log/2021-05-01'
into table ods_log partition (dt='2021-05-01');

4)MySQL数据库的处理

mysql数据库的表通过sqoop采集到HDFS,用的是\t作为分割,那数仓里面ODS层也需要\t作为分割;

5)同步策略

【1】增量同步:订单表

【2】全量同步:商品表

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

3、DIM

dim=dimension

存储为Parquet格式

1)同步策略

全量同步:商品维度,优惠券维度。首日和每日都是全量先导入到ODS再导入到DIM层

特殊:日期,地区(自己处理)

拉链表:用户维度表

4、DWD层

dwd=data warehouse detail

5、dws、

dws= data warehouse service

6、dwt、

dwt=data warehosue topic

7、ads

ads=application data store

 

四、DIM层用户维度拉链表

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)每日装载

 ​​​​​​​

【1】将最新的数据装载到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

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

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';

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

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

相关文章

vue项目 API接口封装

vue项目 API接口封装 01.基础配置创建 分别创建如下文件和文件夹 Object │ .env.development │ .env.production └─src├─api│ index.js│ login.js├─utils│ request.js.env.development 和 .env.production 配置生产环境和开发环境移步&#xf…

Java程序员不得不会的124道面试题(含答案)

1&#xff09;Java 中能创建 volatile 数组吗&#xff1f; 能&#xff0c;Java 中可以创建 volatile 类型数组&#xff0c;不过只是一个指向数组的引用&#xff0c;而不是整个数组。我的意思是&#xff0c;如果改变引用指向的数组&#xff0c;将会受到 volatile 的保护&#x…

多线程常见锁的策略

文章目录前言一、乐观锁和悲观锁1.1 定义1.2 生动有趣滴例子1.3 版本号机制二、读写锁2.1 读写锁的由来2.2 生动有趣de例子2.3 ReentrantReadWriteLock 类三、重量级锁与轻量级锁3.1 定义3.2 生动活泼の例子3.3 自旋锁&#xff08;Spin Lock&#xff09;四、公平锁与非公平锁五…

一名程序员的电脑桌面

配置&#xff1a; 酷呆桌面注册表隐藏快捷方式箭头图标开启桌面模式自动隐藏任务栏 酷呆桌面 在选择酷呆之前&#xff0c;一直是使用的Fences&#xff0c;他的桌面切换功能非常赞&#xff0c;适合划分工作区。但由于强迫症实在是忍受不了肉眼可见的掉帧、黑背景bug&#xff0…

简简单单搞一个实用的Android端搜索框

Hello啊老铁们&#xff0c;今天带来一个非常实用的自定义搜索框&#xff0c;包含了搜索框、热门搜索列表、最近搜索列表等常见的功能&#xff0c;有类似的&#xff0c;大家可以直接复用&#xff0c;将会大大节约您的开发时间&#xff0c;有一点&#xff0c;很负责任的告诉大家&…

最全面的Mybatis教程,从“开局”到“通关”,Ready Go!

前言 本文为SSM框架 【Mybatis】 相关知识&#xff0c;MyBatis 是一款优秀的半自动的ORM持久层框架&#xff0c;下边将对Mybatis的简介、Mybatis的CRUD实现&#xff0c;Mybatis的配置文件&#xff0c;Mybatis的日志配置&#xff0c;resultMap详解&#xff0c;分页实现&#xff…

Vulnhub_CengBox

目录 一 环境异常处理 &#xff08;一&#xff09;nat设置无法正常获取地址 1 单用户模式进入命令行 2 passwd更改 3 修改网络配置文件 二 环境测试 &#xff08;一&#xff09;信息收集 1 端口服务 2 目录扫描 &#xff08;二&#xff09;漏洞测试 1 SQL…

SpringBoot项目的创建(一):通过idea的Spring Initializr来创建(需联网以下载SpringBoot相关的模板)

SpringBoot项目的创建1. 环境准备2. 创建SpringBoot项目3. 创建的SpringBoot项目结构如下4. 添加代码测试web页面效果1. 环境准备 安装jdk和idea&#xff0c;tomcat可不安装&#xff0c;有内置的tomcat 2. 创建SpringBoot项目 打包成war后&#xff0c;需要部署到tomcat中再运…

大数据培训技术操作Flume测试监控

大数据培训技术操作Flume测试监控 1&#xff09;修改/opt/module/flume/conf目录下的flume-env.sh配置&#xff1a; JAVA_OPTS”-Dflume.monitoring.typeganglia -Dflume.monitoring.hosts192.168.9.102:8649 -Xms100m -Xmx200m” 2&#xff09;启动Flume任务 [atguiguh…

关于微前端,你理解到究极奥义了么?

微前端的起源 在微前端这个概念出现之前&#xff0c;我们或多或少都能够联想到另一个词性上有些相似的概念微服务&#xff0c;它从出现后便一直都很火热&#xff0c;并不断催生着后端架构体系的演进&#xff0c;而此刻我们如果细品一下这微字头的两兄弟&#xff0c;探究他们的诞…

大白鲨优化算法(WSO)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2022年Java发展怎么样?现在学了Java技术出来是否还能找到工作?

马云爸爸说过&#xff0c;未来的制造业要的不是石油&#xff0c;最大的能源应该是数据。不管你是上网购物&#xff0c;还是手机浏览咨询&#xff0c;甚至是政府机构&#xff0c;大型跨国集团系统&#xff0c;银行&#xff0c;背后的庞大的数据处理都是由Java来完成&#xff0c;…

FPGA时序约束02——不同时序路径的分析方法

前言前文&#xff08;FPGA时序约束01——基本概念&#xff09;中介绍了四种时序路径&#xff0c;如下图所示。 分别是触发器到触发器&#xff0c;触发器到输出端&#xff0c;输入端到触发器&#xff0c;输入端到输出端&#xff0c;其中输入端到输出端是纯组合逻辑路径&#xff…

外包做的系统宕机了,逼得我重新设计一套MySQL数据库架构!

V-xin&#xff1a;ruyuanhadeng获得600页原创精品文章汇总PDF 目录 一般业务系统运行流程图一台 4 核 8G 的机器能扛多少并发量呢&#xff1f;高并发来袭时数据库会先被打死吗&#xff1f;8 核 16G 的数据库每秒大概可以抗多少并发压力&#xff1f;数据库架构可以从哪些方面优…

[Android移动安全渗透基础教程] 如何为Android Studio 模拟器(AVD)设置Frida?

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 0x01 如何为Android Studio 模拟器&#xff08;AVD&#xff09;设置Frid…

全志V853 NPU 系统介绍

NPU 系统介绍 V853 芯片内置一颗 NPU&#xff0c;其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换&#xff0c;支持 OpenCL、OpenVX、android NN 与 ONNX 的 API 调用&#xff0c;同时也支持导入大量常用的深度学习模型。 NPU 系统架构 NPU 的系统架构如下…

猿创征文| 六款我的开发者宝藏工具箱

目录 No.1 | 亿图图示 简介&#xff1a; 推荐之处&#xff1a; 下载途径&#xff1a; Show time&#xff1a; No.2 | 飞书 简介&#xff1a; 推荐之处&#xff1a; 下载途径&#xff1a; Show time&#xff1a; No.3 | 迅捷PDF转换器 简介&#xff1a; 推荐之处&#xff1a; …

Allegro SigXplorer 等长设置方法-比较简单

使用方法示一&#xff1a; 1、如图SDRAM的连线U2到U5、U6和U7的地址线均需要设置等长&#xff0c;常规我们对每个网络设置pin pair&#xff0c;会比较繁琐&#xff0c;设过的人都知道。 使用方法二&#xff1a; 2、开始设置&#xff0c;打开规则管理器&#xff0c;在电气规则…

HTML爱心代码 | 一起体验理工男的极致浪漫(电视剧男主同款)

写在前面 大家好&#xff0c;我是陈橘又青&#xff0c;今天中午刷微博&#xff0c;看到最近《点燃我温暖你》中男主角——理工男李峋的爱心代码撩到了无数人&#xff0c;于是把代码开源分享给大家。 文章目录写在前面运行示例完整代码保姆级运行教学添加背景图片修改爱心颜色运…

软件工程毕业设计课题(17)基于python的毕业设计python鲜花水果商城系统毕设作品源码

项目背景和意义 目的&#xff1a;伴随着互联网技术的不断发展和完善&#xff0c;在人们的生活和工作的各个方面&#xff0c;互联网都有着非常重大的影响。伴随着国内电子商务行业的迅猛发展&#xff0c;消费者现在能够轻松的实现足不出户的&#xff0c;仅仅通过网络购物平台就可…