单张表超过30个字段_拉链表
為什么要做拉鏈表
拉鏈表適合于:數(shù)據(jù)會(huì)發(fā)生新增和變化,但是大部分是不變的,且是緩慢變化的(如電商中用戶信息表中的手機(jī)號(hào)不可能每天都變化),如果是快速變化的(如每天一變),則每天做全量更新(事務(wù)型事實(shí)表)。主要目的是節(jié)省存儲(chǔ)空間。
拉鏈表的使用場(chǎng)景
在數(shù)據(jù)倉庫的數(shù)據(jù)模型設(shè)計(jì)過程中,經(jīng)常會(huì)遇到下面這種表的設(shè)計(jì):
- 1 有一些表的數(shù)據(jù)量很大,比如一張用戶表,大約10億條記錄,50個(gè)字段,這種表,即使使用ORC壓縮,單張表的存儲(chǔ)也會(huì)超過100G,在HDFS使用雙備份或者三備份的話就更大一些。
- 2 表中的部分字段會(huì)被update更新操作,如用戶聯(lián)系方式,產(chǎn)品的描述信息,訂單的狀態(tài)等等。
- 3 需要查看某一個(gè)時(shí)間點(diǎn)或者時(shí)間段的歷史快照信息,比如,查看某一個(gè)訂單在歷史某一個(gè)時(shí)間點(diǎn)的狀態(tài)。
- 4 表中的記錄變化的比例和頻率不是很大,比如,總共有10億的用戶,每天新增和發(fā)生變化的有200萬左右,變化的比例占的很小
什么是拉鏈表
記錄每條信息的生命周期,一旦一條信息的生命周期結(jié)束,就重新開始一條新紀(jì)錄,并把當(dāng)前日期放入生效日期。 如果當(dāng)前日期至今有效,在結(jié)束日期放入一個(gè)最大值,例如(9999-99-99)
- 優(yōu)勢(shì):訂單1經(jīng)歷了四個(gè)生命周期,如果每天增量同步數(shù)據(jù),則一年有365條數(shù)據(jù),而拉鏈表只會(huì)產(chǎn)生4條數(shù)據(jù)
制作拉鏈表
首先初始化拉鏈表
通常要在原表的基礎(chǔ)上加入start_date,end_date,并從原表導(dǎo)入數(shù)據(jù)到拉鏈表
drop table if exists dwd_order_info_his; create external table dwd_order_info_his(`id` string COMMENT '訂單編號(hào)',`order_status` string COMMENT '訂單狀態(tài)',`start_date` string COMMENT '有效開始日期',`end_date` string COMMENT '有效結(jié)束日期' ) COMMENT '訂單拉鏈表'創(chuàng)建臨時(shí)表整個(gè)中間數(shù)據(jù)
臨時(shí)表和拉鏈表表結(jié)構(gòu)一致,只是為了存儲(chǔ)中間過程。
drop table if exists dwd_order_info_his_tmp; create external table dwd_order_info_his_tmp(`id` string COMMENT '訂單編號(hào)',`order_status` string COMMENT '訂單狀態(tài)',`start_date` string COMMENT '有效開始日期',`end_date` string COMMENT '有效結(jié)束日期' ) COMMENT '訂單拉鏈臨時(shí)表'向臨時(shí)表中插入數(shù)據(jù)
插入前,拉鏈表數(shù)據(jù)
訂單新增表數(shù)據(jù)
插入數(shù)據(jù)后
訂單1和訂單2,訂單狀態(tài)都發(fā)生了改變,產(chǎn)生了新數(shù)據(jù)
具體sql
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,'2019-02-14' start_date,'9999-99-99' end_date from dwd_order_info where dt='2019-02-14'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='2019-02-14' ) oion oh.id=oi.id )his order by his.id, start_date;分為兩個(gè)部分?jǐn)?shù)據(jù) 第一部分把新增修改表直接插入,這部分?jǐn)?shù)據(jù)都是新鮮的,end_date是9999-99-99
第二部分是原拉鏈表和新增變化表做左連接,原表存在id且終止時(shí)間為無限的數(shù)據(jù)會(huì)保留,說明這部分?jǐn)?shù)據(jù)需要變更。(如果右表id為空,說明這部分?jǐn)?shù)據(jù)沒有任何改變,end_date保持不變,如果右表數(shù)據(jù)存在,說明經(jīng)過了改變,則,end_date需要減1),所以這部分完成了歷史數(shù)據(jù)的更改
將拉鏈表數(shù)據(jù)用臨時(shí)表覆蓋
因?yàn)閔ive修改字段值不方便,直接全變覆蓋
insert overwrite table dwd_order_info_his select * from dwd_order_info_his_tmp;總結(jié)
以上是生活随笔為你收集整理的单张表超过30个字段_拉链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php mysql连续签到跨月_PHP连
- 下一篇: 禅道 bug状态 open_小工具大帮手