一、全量表:df表,有無變化都要上報,只有一個分區或者沒有分區,每次往全量表里面寫數據都會覆蓋之前的數據,不能記錄數據的歷史變化,只能截止到當前最新、全量的數據
二、增量表:每天新增的數據和改變的數據都會存儲在當日的分區中;增量表記錄每次增加的量,只報變化量,無變化的不用報;增量表設計過程,假設以18號與19號數據為例
-- 1、找出19號未修改的數據,寫入當前分區 INSERT OVERWARITE dwd.user_info_di PARTITION(p_dymd='2021-12-19') WITH t1 AS ( SELECT * FROM dwd.user_info_di WHERE p_dymd = '2021-12-18' ), t2 AS ( SELECT * FROM ods.user_info WHERE p_dymd = '2021-12-19' ) SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.user_id = t2.user_id WHERE t2.user_id is null -- 2、將19號新增和變化的數據寫入當前分區 INSERT INTO TABLE dwd.user_info_di PARTITION(p_dymd='2021-12-19') SELECT * FROM ods.user_info WHERW p_dymd = '2021-12-19'
-- 3、一般增量表只保存7天的數量
ALTER TABLE dwd.user_info_di DROP IF EXIST PARTITION(p_dymd='2021-12-19')
特殊增量表:da表,一般是埋點日志等,每天的數據存儲在當天的分區里面,數據產生之后就不會再發生變化了。
三、快照表:因為全量表無法反映歷史的變化,這時快照表就可以使用了,快照表記錄截止數據日期的全量數據(每個分區都是記錄截止當前分區日期的全量數據),但是在數據量大的情況下,每個分區存儲的都是全量數據,數據冗余和浪費存儲空間;
四、切片表:根據基礎表,往往只反映某一個維度的相應數據,數據只有一個維度或者某一事實條件數據;
五、拉鏈表:能夠解決快照表數據冗余問題,還能維護數據歷史狀態和最新狀態,記錄截止數據日期的全量數據,一個事物從開始,一直到當前狀態的所有變化信息;
- 緩慢變化維(SCD):拉鏈表不是SCD,它只是用來處理緩慢變化維的一種手段而已。將分析的角度存放在維度表中,但維度表里的數據可能發生一些變化,盡管可能跨越很久,例如用戶信息表;緩慢變化維處理的方式一般如下:
1)重寫覆蓋:與業務系統保持一致,直接更新為最新的狀態數據即可;適用於:數據必須正確,比如客戶的身份證;不需要考慮歷史變化維度,沒有意義沒有價值的維度;優點是直接更新即可,缺點無法恢復,不能查看歷史變化
2)增加新行:更新歷史數據時間戳,新增新行記錄新值;適用於僅需保持歷史數據的業務場景,相應的事實表的的關聯需要更新為最新的id

3)增加新列:如果某個維度發生多次變化,會產生列爆炸
4)拉鏈表
- 拉鏈表的具體使用
1)同步ods層數據
drop table if exists ods.ods_trade_shops; create table ods.ods_trade_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 (`dt` string) row format delimited fields terminated by ','; ../shops/shop-2020-07-01.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-2020-07-02.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 '/app/softwares/2020-07-01.dat' into table ods.ods_trade_shops partition(dt='2020-07-01')
2)創建拉鏈表
drop table if exists dim.dim_trade_shops_dz; create table dim.dim_trade_shops_dz( `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 '修改日期', -- 拉鏈表新增兩列,生效起始時間和失效結束時間 `startdate` string COMMENT '生效起始日期', `enddate` string COMMENT '失效結束日期' ) comment '商家信息表';
3)初始化拉鏈表
-- 初始化拉鏈表 insert overwrite table dim.dim_trade_shops_dz 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.ods_trade_shops where dt = '2020-07-01'; -- 2號維表發生變化:1、取出當天記錄與前一天關聯,存在表示維表更新,將失效時間記為前一天 insert overwrite table dim.dim_trade_shops_dz 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.ods_trade_shops
where dt = '2020-07-02' union all select b.shopid, b.userid ,b.areaid , b.shopname, b.shoplevel, b.status, b.createtime, b.modifytime, b.startdate, CASE WHEN a.shopid is not null and b.enddate ='9999-12-31' THEN date_add('2020-07-02',-1) ELSE b.enddate end as enddate from (select * from ods.ods_trade_shops where dt='2020-07-02') a right join dim.dim_trade_shops b on a.shopid = b.shopid;
