数仓之全量表、增量表、快照表、切片表、拉链表

本文详细介绍了数据仓库中常见的表类型,包括全量表、增量表、快照表、切片表和拉链表等,并重点阐述了拉链表的概念、应用场景及实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、全量表

二、增量表

三、快照表

四、切片表

五、拉链表

1、概念

2、拉链表的使用场景

3、拉链表的实现方法

1.同步ods数据

2.创建拉链表

3.初始化拉链表

4.新增增量数据

5.对比上日变化数据关链操作


一、全量表

记录每天的所有的最新状态的数据,有无变化都要上报,每次往全量表里面写数据都会覆盖之前的数据

缺点:不能记录数据的历史变化,只能截止到当前最新、全量的数据


二、增量表

记录每天的新增的数据和改变的数据。


三、快照表

按日分区,记录截止数据日期的全量数据(每个分区都是记录截止当前分区日期的全量数据)。

优点:可以反映历史的变化 

缺点:在数据量大的情况下,每个分区存储的都是全量数据,数据冗余和浪费存储空间


四、切片表

切片表根据基础表,往往只反映某一个维度的相应数据。其表结构与基础表结构相同,但数据往往只有某一维度,或者某一个事实条件的数据


五、拉链表

1、概念

记录一个事物从开始,一直到当前状态的所有变化的信息。(极限存储)

优点:能够解决快照表数据冗余问题,还能维护数据历史状态和最新状态,记录截止数据日期的全量数据

2、拉链表的使用场景

缓慢变化维SCD(表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等;表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。)

数据量很大(比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些;需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态)

3、拉链表的实现方法

1.同步ods数据

drop table if exists ods.shops;
create table ods.shops(
  `shopid` int COMMENT '商铺ID',
  `userid` int COMMENT '商铺负责人', 
  `areaid` int COMMENT '区域ID',
  `shopname` string COMMENT '商铺名称',
  `shoplevel` int COMMENT '商铺等级',
  `status` int COMMENT '商铺状态',
  `createtime` string COMMENT '创建日期',
  `modifytime` string COMMENT  '修改日期'
) COMMENT '商家信息表'
PARTITIONED BY (`ds` string)
row format delimited fields terminated by ',';

../shops/shop-2022-09-19.dat
100050,1,100225,WSxxx营超市,1,1,2020-06-28,2020-07-01 13:22:22
100052,2,100236,新鲜xxx旗舰店,1,1,2020-06-28,2020-07-01 13:22:22
100053,3,100011,华为xxx旗舰店,1,1,2020-06-28,2020-07-01 13:22:22
100054,4,100159,小米xxx旗舰店,1,1,2020-06-28,2020-07-01 13:22:22
100055,5,100211,苹果xxx旗舰店,1,1,2020-06-28,2020-07-01 13:22:22

../shops/shop-2022-09-20.dat
100057,7,100311,三只xxx鼠零食,1,1,2020-06-28,2020-07-02 13:22:22
100058,8,100329,良子xxx铺美食,1,1,2020-06-28,2020-07-02 13:22:22
100054,4,100159,小米xxx旗舰店,2,1,2020-06-28,2020-07-02 13:22:22
100055,5,100211,苹果xxx旗舰店,2,1,2020-06-28,2020-07-02 13:22:22

-- 加载数据
load data local inpath '/2022-09-19.dat' into table ods.shops partition(ds='2022-09-19')

2.创建拉链表

drop table if exists dim.shops_his;
create table dim.shops_his(
  `shopid` int COMMENT '商铺ID',
  `userid` int COMMENT '商铺负责人', 
  `areaid` int COMMENT '区域ID',
  `shopname` string COMMENT '商铺名称',
  `shoplevel` int COMMENT '商铺等级',
  `status` int COMMENT '商铺状态',
  `createtime` string COMMENT '创建日期',
  `modifytime` string COMMENT  '修改日期',
  -- 拉链表新增两列,生效起始时间和失效结束时间
  `start_date` string  COMMENT '生效起始日期',
  `end_date` string  COMMENT '失效结束日期'
) comment '商家信息表';

3.初始化拉链表

-- 初始化拉链表
insert overwrite table dim.shops_his
select 
     shopid
    ,userid
    ,areaid
    ,shopname
    ,shoplevel
    ,status
    ,createtime
    ,modifytime
    ,case when modifytime is not null then substr(modifytime, 0, 10)
          else substr(createtime, 0, 10) 
     end as start_date 
    ,'9999-12-31' as end_date
from ods.shops
where ds = '2022-09-19'; 

4.新增增量数据

insert into table dim.shops_his
select 
     shopid
    ,userid
    ,areaid
    ,shopname
    ,shoplevel
    ,status
    ,createtime
    ,modifytime
    ,case when modifytime is not null then substr(modifytime, 0, 10)
          else substr(createtime, 0, 10) 
     end as startdate
    ,'9999-12-31' as enddate
from ods.shops
where ds = '2022-09-20'; 

5.对比上日变化数据关链操作

insert into table dim.shops_his
select 
     b.shopid
    ,b.userid
    ,b.areaid
    ,b.shopname
    ,b.shoplevel
    ,b.status
    ,b.createtime
    ,b.modifytime
    ,CASE WHEN a.shopid is not null and b.enddate ='9999-12-31' THEN date_add('2022-09-20',-1) 
          ELSE b.enddate 
     end as end_date 
     --上日若存在结束日期置为上日,不存在置为最大日期
from (select * from ods.shops where ds='2022-09-20') a
right join dim.shops_his b on a.shopid = b.shopid;

### **量表全量表拉链的应用场景解析** #### **1. 核心概念对比** ```mermaid graph LR 全量表-->|每日全量替换|Complete[据完整性] 量表-->|仅新变更|Delta[处理效率] 拉链-->|历史追溯|History[时态分析] ``` #### **2. 典型应用场景** | 类型 | 适用场景 | 示例 | |----------|--------------------------------------------------------------------------|----------------------------------------------------------------------| | **全量表** | 1. 据量小的维度<br>2. 需要绝对准确性的基准据<br>3. 无变更历史需求 | 国家编码、产品基础信息 | | **量表** | 1. 事件流水据<br>2. 大据量的事实<br>3. 仅需最新状态的场景 | 用户浏览日志、交易流水记录 | | **拉链** | 1. 缓慢变化维度(SCD)<br>2. 需要历史追溯的业务<br>3. 变化频率适中的维度据 | 用户会员等级变更记录、商品价格变更历史 | #### **3. 技术实现示例** **(1)量表处理(Spark实现)** ```python # 每日量合并 new_data = spark.read.parquet("/new_data/") existing_data = spark.read.parquet("/full_data/") result = existing_data.union(new_data).dropDuplicates(["id"]) result.write.mode("overwrite").parquet("/full_data/") ``` **(2)拉链SQL实现** ```sql -- 拉链结构示例 CREATE TABLE user_chain ( user_id BIGINT, name STRING, start_date DATE, end_date DATE, is_current BOOLEAN ); -- 更新逻辑 INSERT OVERWRITE TABLE user_chain SELECT user_id, name, CASE WHEN new_rec THEN effective_date ELSE start_date END, CASE WHEN expired THEN effective_date ELSE end_date END, NOT expired AS is_current FROM ( -- 新旧据比对逻辑 SELECT ..., LEAD(effective_date) OVER (PARTITION BY user_id ORDER BY effective_date) IS NULL AS new_rec, effective_date < CURRENT_DATE() AS expired FROM source_data ); ``` #### **4. 性能对比分析** | 维度 | 全量表 | 量表 | 拉链 | |--------------|-------------|-------------|---------------| | **存储成本** | 高(每日全量) | 低(仅量) | 中(历史版本) | | **查询效率** | 快(无JOIN) | 快(据量少) | 慢(需时间筛选) | | **ETL复杂度** | 低 | 中 | 高 | | **历史追溯** | 不支持 | 有限支持 | 完全支持 | #### **5. 混合使用案例** ```sql -- 电商平台典型组合 WITH -- 全量维度 product_base AS (SELECT * FROM dim_product WHERE dt='2023-12-01'), -- 量事实 order_new AS (SELECT * FROM fact_order WHERE dt='2023-12-01'), -- 拉链维度 user_level AS ( SELECT * FROM dim_user_level WHERE '2023-12-01' BETWEEN start_date AND end_date ) -- 业务查询 SELECT ... FROM order_new JOIN product_base USING(product_id) JOIN user_level USING(user_id); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值