ODS(Operational Data Store)層存放您從業務系統獲取的最原始的數據,是其他上層數據的源數據。業務數據系統中的數據通常為非常細節的數據,經過長時間累積,且訪問頻率很高,是面向應用的數據。
在構建MaxCompute數據倉庫的表之前,您需要首先了解MaxCompute支持的數據類型版本說明。
數據引入層表設計
本教程中,在ODS層主要包括的數據有:交易系統訂單詳情、用戶信息詳情、商品詳情等。這些數據未經處理,是最原始的數據。邏輯上,這些數據都是以二維表的形式存儲。雖然嚴格的說ODS層不屬于數倉建模的范疇,但是合理的規劃ODS層并做好數據同步也非常重要。本教程中,使用了6張ODS表:
記錄用于拍賣的商品信息:s_auction。
記錄用于正常售賣的商品信息:s_sale。
記錄用戶詳細信息:s_users_extra。
記錄新增的商品成交訂單信息:s_biz_order_delta。
記錄新增的物流訂單信息:s_logistics_order_delta。
記錄新增的支付訂單信息:s_pay_order_delta。
表或字段命名盡量和業務系統保持一致,但是需要通過額外的標識來區分增量和全量表。例如,我們通過_delta來標識該表為增量表。
命名時需要特別注意沖突處理,例如不同業務系統的表可能是同一個名稱。為區分兩個不同的表,您可以將這兩個同名表的來源數據庫名稱作為后綴或前綴。例如,表中某些字段的名稱剛好和關鍵字重名了,可以通過添加_col后綴解決。
ODS層設計規范
ODS層表命名、數據同步任務命名、數據產出及生命周期管理及數據質量規范請參見ODS層設計規范。
建表示例
為方便您使用,集中提供建表語句如下。更多建表信息,請參見表操作。
CREATE TABLE IF NOT EXISTS s_auction
(
id STRING COMMENT '商品ID',
title STRING COMMENT '商品名',
gmt_modified STRING COMMENT '商品最后修改日期',
price DOUBLE COMMENT '商品成交價格,單位元',
starts STRING COMMENT '商品上架時間',
minimum_bid DOUBLE COMMENT '拍賣商品起拍價,單位元',
duration STRING COMMENT '有效期,銷售周期,單位天',
incrementnum DOUBLE COMMENT '拍賣價格的增價幅度',
city STRING COMMENT '商品所在城市',
prov STRING COMMENT '商品所在省份',
ends STRING COMMENT '銷售結束時間',
quantity BIGINT COMMENT '數量',
stuff_status BIGINT COMMENT '商品新舊程度 0 全新 1 閑置 2 二手',
auction_status BIGINT COMMENT '商品狀態 0 正常 1 用戶刪除 2 下架 3 從未上架',
cate_id BIGINT COMMENT '商品類目ID',
cate_name STRING COMMENT '商品類目名稱',
commodity_id BIGINT COMMENT '品類ID',
commodity_name STRING COMMENT '品類名稱',
umid STRING COMMENT '買家umid'
)
COMMENT '商品拍賣ODS'
PARTITIONED BY (ds STRING COMMENT '格式:YYYYMMDD')
LIFECYCLE 400;
CREATE TABLE IF NOT EXISTS s_sale
(
id STRING COMMENT '商品ID',
title STRING COMMENT '商品名',
gmt_modified STRING COMMENT '商品最后修改日期',
starts STRING COMMENT '商品上架時間',
price DOUBLE COMMENT '商品價格,單位元',
city STRING COMMENT '商品所在城市',
prov STRING COMMENT '商品所在省份',
quantity BIGINT COMMENT '數量',
stuff_status BIGINT COMMENT '商品新舊程度 0 全新 1 閑置 2 二手',
auction_status BIGINT COMMENT '商品狀態 0 正常 1 用戶刪除 2 下架 3 從未上架',
cate_id BIGINT COMMENT '商品類目ID',
cate_name STRING COMMENT '商品類目名稱',
commodity_id BIGINT COMMENT '品類ID',
commodity_name STRING COMMENT '品類名稱',
umid STRING COMMENT '買家umid'
)
COMMENT '商品正常購買ODS'
PARTITIONED BY (ds STRING COMMENT '格式:YYYYMMDD')
LIFECYCLE 400;
CREATE TABLE IF NOT EXISTS s_users_extra
(
id STRING COMMENT '用戶ID',
logincount BIGINT COMMENT '登錄次數',
buyer_goodnum BIGINT COMMENT '作為買家的好評數',
seller_goodnum BIGINT COMMENT '作為賣家的好評數',
level_type BIGINT COMMENT '1 一級店鋪 2 二級店鋪 3 三級店鋪',
promoted_num BIGINT COMMENT '1 A級服務 2 B級服務 3 C級服務',
gmt_create STRING COMMENT '創建時間',
order_id BIGINT COMMENT '訂單ID',
buyer_id BIGINT COMMENT '買家ID',
buyer_nick STRING COMMENT '買家昵稱',
buyer_star_id BIGINT COMMENT '買家星級 ID',
seller_id BIGINT COMMENT '賣家ID',
seller_nick STRING COMMENT '賣家昵稱',
seller_star_id BIGINT COMMENT '賣家星級ID',
shop_id BIGINT COMMENT '店鋪ID',
shop_name STRING COMMENT '店鋪名稱'
)
COMMENT '用戶擴展表'
PARTITIONED BY (ds STRING COMMENT 'yyyymmdd')
LIFECYCLE 400;
CREATE TABLE IF NOT EXISTS s_biz_order_delta
(
biz_order_id STRING COMMENT '訂單ID',
pay_order_id STRING COMMENT '支付訂單ID',
logistics_order_id STRING COMMENT '物流訂單ID',
buyer_nick STRING COMMENT '買家昵稱',
buyer_id STRING COMMENT '買家ID',
seller_nick STRING COMMENT '賣家昵稱',
seller_id STRING COMMENT '賣家ID',
auction_id STRING COMMENT '商品ID',
auction_title STRING COMMENT '商品標題 ',
auction_price DOUBLE COMMENT '商品價格',
buy_amount BIGINT COMMENT '購買數量',
buy_fee BIGINT COMMENT '購買金額',
pay_status BIGINT COMMENT '支付狀態 1 未付款 2 已付款 3 已退款',
logistics_id BIGINT COMMENT '物流ID',
mord_cod_status BIGINT COMMENT '物流狀態 0 初始狀態 1 接單成功 2 接單超時3 攬收成功 4攬收失敗 5 簽收成功 6 簽收失敗 7 用戶取消物流訂單',
status BIGINT COMMENT '狀態 0 訂單正常 1 訂單不可見',
sub_biz_type BIGINT COMMENT '業務類型 1 拍賣 2 購買',
end_time STRING COMMENT '交易結束時間',
shop_id BIGINT COMMENT '店鋪ID'
)
COMMENT '交易成功訂單日增量表'
PARTITIONED BY (ds STRING COMMENT 'yyyymmdd')
LIFECYCLE 7200;
CREATE TABLE IF NOT EXISTS s_logistics_order_delta
(
logistics_order_id STRING COMMENT '物流訂單ID ',
post_fee DOUBLE COMMENT '物流費用',
address STRING COMMENT '收貨地址',
full_name STRING COMMENT '收貨人全名',
mobile_phone STRING COMMENT '移動電話',
prov STRING COMMENT '省份',
prov_code STRING COMMENT '省份ID',
city STRING COMMENT '市',
city_code STRING COMMENT '城市ID',
logistics_status BIGINT COMMENT '物流狀態
1 - 未發貨
2 - 已發貨
3 - 已收貨
4 - 已退貨
5 - 配貨中',
consign_time STRING COMMENT '發貨時間',
gmt_create STRING COMMENT '訂單創建時間',
shipping BIGINT COMMENT '發貨方式
1,平郵
2,快遞
3,EMS',
seller_id STRING COMMENT '賣家ID',
buyer_id STRING COMMENT '買家ID'
)
COMMENT '交易物流訂單日增量表'
PARTITIONED BY (ds STRING COMMENT '日期')
LIFECYCLE 7200;
CREATE TABLE IF NOT EXISTS s_pay_order_delta
(
pay_order_id STRING COMMENT '支付訂單ID',
total_fee DOUBLE COMMENT '應支付總金額 (數量*單價)',
seller_id STRING COMMENT '賣家ID',
buyer_id STRING COMMENT '買家ID',
pay_status BIGINT COMMENT '支付狀態
1等待買家付款,
2等待賣家發貨,
3交易成功',
pay_time STRING COMMENT '付款時間',
gmt_create STRING COMMENT '訂單創建時間',
refund_fee DOUBLE COMMENT '退款金額(包含運費)',
confirm_paid_fee DOUBLE COMMENT '已經確認收貨的金額'
)
COMMENT '交易支付訂單增量表'
PARTITIONED BY (ds STRING COMMENT '日期')
LIFECYCLE 7200;
數據引入層存儲
為了滿足歷史數據分析需求,您可以在ODS層表中添加時間維度作為分區字段。實際應用中,您可以選擇采用增量、全量存儲或拉鏈存儲的方式。
增量存儲
以天為單位的增量存儲,以業務日期作為分區,每個分區存放日增量的業務數據。舉例如下:
1月1日,用戶A訪問了A公司電商店鋪B,A公司電商日志產生一條記錄t1。1月2日,用戶A又訪問了A公司電商店鋪C,A公司電商日志產生一條記錄t2。采用增量存儲方式,t1將存儲在1月1日這個分區中,t2將存儲在1月2日這個分區中。
1月1日,用戶A在A公司電商網購買了B商品,交易日志將生成一條記錄t1。1月2日,用戶A又將B商品退貨了,交易日志將更新t1記錄。采用增量存儲方式,初始購買的t1記錄將存儲在1月1日這個分區中,更新后的t1將存儲在1月2日這個分區中。
說明交易、日志等事務性較強的ODS表適合增量存儲方式。這類表數據量較大,采用全量存儲的方式存儲成本壓力大。此外,這類表的下游應用對于歷史全量數據訪問的需求較小(此類需求可通過數據倉庫后續匯總后得到)。例如,日志類ODS表沒有數據更新的業務過程,因此所有增量分區UNION在一起就是一份全量數據。
全量存儲
以天為單位的全量存儲,以業務日期作為分區,每個分區存放截止到業務日期為止的全量業務數據。例如,1月1日,賣家A在A公司電商網發布了B、C兩個商品,前端商品表將生成兩條記錄t1、t2。1月2日,賣家A將B商品下架了,同時又發布了商品D,前端商品表將更新記錄t1,同時新生成記錄t3。采用全量存儲方式,在1月1日這個分區中存儲t1和t2兩條記錄,在1月2日這個分區中存儲更新后的t1以及t2、t3記錄。
說明對于小數據量的緩慢變化維度數據,例如商品類目,可直接使用全量存儲。
拉鏈存儲
拉鏈存儲通過新增兩個時間戳字段(start_dt和end_dt),將所有以天為粒度的變更數據都記錄下來,通常分區字段也是這兩個時間戳字段。
拉鏈存儲舉例如下。
商品
start_dt
end_dt
賣家
狀態
B
20160101
20160102
A
上架
C
20160101
30001231
A
上架
B
20160102
30001231
A
下架
這樣,下游應用可以通過限制時間戳字段來獲取歷史數據。例如,用戶訪問1月1日數據,只需限制
start_dt<=20160101
并且end_dt>20160101
。
緩慢變化維度
MaxCompute不推薦使用代理鍵,推薦使用自然鍵作為維度主鍵,主要原因有兩點:
MaxCompute是分布式計算引擎,生成全局唯一的代理鍵工作量非常大。當遇到大數據量情況下,這項工作就會更加復雜,且沒有必要。
使用代理鍵會增加ETL的復雜性,從而增加ETL任務的開發和維護成本。
在不使用代理鍵的情況下,緩慢變化維度可以通過快照方式處理。
快照方式下數據的計算周期通常為每天一次。基于該周期,處理維度變化的方式為每天一份全量快照。
例如商品維度,每天保留一份全量商品快照數據。任意一天的事實表均可以取到當天的商品信息,也可以取到最新的商品信息,通過限定日期,采用自然鍵進行關聯即可。該方式的優勢主要有以下兩點:
處理緩慢變化維度的方式簡單有效,開發和維護成本低。
使用方便,易于理解。數據使用方只需要限定日期即可取到當天的快照數據。任意一天的事實快照與任意一天的維度快照通過維度的自然鍵進行關聯即可。
該方法的弊端主要是存儲空間的極大浪費。例如某維度每天的變化量占總體數據量比例很低,極端情況下,每天無變化,這種情況下存儲浪費嚴重。該方法主要實現了通過犧牲存儲獲取ETL效率的優化和邏輯上的簡化。請避免過度使用該方法,且必須要有對應的數據生命周期制度,清除無用的歷史數據。