告訴我!數(shù)據(jù)倉庫 DWD 層怎么建?
DWD(Data Warehouse Detail)層是數(shù)據(jù)倉庫體系中的明細(xì)數(shù)據(jù)層,位于ODS(Operational Data Store,原始數(shù)據(jù)層)之上,DIM(維度層)和DWS(數(shù)據(jù)服務(wù)層)之下。它是數(shù)據(jù)倉庫的核心加工區(qū)域,承擔(dān)著將原始數(shù)據(jù)轉(zhuǎn)換為可用分析數(shù)據(jù)的重要職責(zé)。
DWD層的主要特點(diǎn)是:
- 面向主題:按業(yè)務(wù)領(lǐng)域進(jìn)行數(shù)據(jù)組織
- 粒度統(tǒng)一:保持相同業(yè)務(wù)過程的數(shù)據(jù)粒度一致
- 結(jié)構(gòu)規(guī)范:字段命名和定義遵循統(tǒng)一標(biāo)準(zhǔn)
- 歷史完整:保留歷史變更數(shù)據(jù),確保可追溯性
一、DWD層建設(shè)的基本思路
1. 業(yè)務(wù)分域設(shè)計(jì)
DWD層首先應(yīng)該按照業(yè)務(wù)域(Domain)進(jìn)行劃分,常見的業(yè)務(wù)域包括:用戶域:用戶基礎(chǔ)信息、注冊、登錄、地址等
- 商品域:商品、類目、品牌等基礎(chǔ)數(shù)據(jù)
- 交易域:訂單、支付、退款等交易過程數(shù)據(jù)
- 流量域:點(diǎn)擊、曝光、跳出等用戶行為數(shù)據(jù)
- 營銷域:活動、優(yōu)惠券、秒殺等營銷數(shù)據(jù)
- 庫存域:庫存、倉儲等供應(yīng)鏈數(shù)據(jù)
- 互動域:評論、收藏、分享等社交數(shù)據(jù)
這種分域方式讓數(shù)據(jù)架構(gòu)更清晰,方便不同業(yè)務(wù)部門使用自己關(guān)心的數(shù)據(jù)。
2. 明確數(shù)據(jù)模型類型
DWD層主要包含兩類數(shù)據(jù)模型:
- 事實(shí)表:記錄業(yè)務(wù)事件,通常包含度量值和外鍵
- 維度表:描述業(yè)務(wù)對象的屬性,如用戶、商品、時間等
根據(jù)數(shù)據(jù)更新方式,DWD表可以分為:
- 全量表(Full):每次加載會覆蓋所有歷史數(shù)據(jù)
- 增量表(Inc):只加載新增或變化的數(shù)據(jù)
- 拉鏈表:記錄數(shù)據(jù)的歷史變更,保留所有版本信息
3. 數(shù)據(jù)加工規(guī)范
DWD層的數(shù)據(jù)加工遵循以下規(guī)范:字段規(guī)范:統(tǒng)一字段命名和數(shù)據(jù)類型,如id、create_time等
- 數(shù)據(jù)清洗:處理空值、異常值、重復(fù)值等
- 數(shù)據(jù)轉(zhuǎn)換:類型轉(zhuǎn)換、編碼轉(zhuǎn)換、格式標(biāo)準(zhǔn)化
- 數(shù)據(jù)整合:關(guān)聯(lián)多個來源的數(shù)據(jù),豐富信息維度
- 指標(biāo)計(jì)算:生成基礎(chǔ)派生指標(biāo)
4. 分區(qū)與性能優(yōu)化
為提高查詢效率,DWD層通常采用分區(qū)策略:
- 按時間分區(qū):最常見的方式,如按天分區(qū)(k1字段)
- 按業(yè)務(wù)分區(qū):某些場景下按業(yè)務(wù)線或地區(qū)分區(qū)
- 復(fù)合分區(qū):時間+業(yè)務(wù)的組合分區(qū)策略
二、DWD層建設(shè)實(shí)踐案例 - 用戶地址表設(shè)計(jì)與實(shí)現(xiàn)
下面以dwd_user_address_full表為例,詳細(xì)說明DWD層表的設(shè)計(jì)和實(shí)現(xiàn)過程。
1. 需求分析
用戶地址信息是電商系統(tǒng)的重要基礎(chǔ)數(shù)據(jù),需要支持:
- 用戶歷史地址查詢
- 配送范圍分析
- 區(qū)域銷售分布統(tǒng)計(jì)
2. 數(shù)據(jù)源分析
從ODS層,我們有兩個相關(guān)表:
- ods_user_address_full:用戶地址基本信息
- ods_base_province_full:省份信息
通過分析表結(jié)構(gòu),發(fā)現(xiàn):
- 用戶地址表包含用戶ID、省份ID等基本信息
- 省份表包含省份名稱、地區(qū)編碼等信息
- 缺少專門的城市和區(qū)縣表
3. 表結(jié)構(gòu)設(shè)計(jì)
CREATE TABLE dwd.dwd_user_address_full
(
`id` VARCHAR(255) COMMENT '地址ID',
`k1` DATE COMMENT '數(shù)據(jù)日期',
`user_id` STRING COMMENT '用戶ID',
`province_id` STRING COMMENT '省份ID',
`province_name` STRING COMMENT '省份名稱',
`city_id` STRING COMMENT '城市ID',
`city_name` STRING COMMENT '城市名稱',
`district_id` STRING COMMENT '區(qū)縣ID',
`district_name` STRING COMMENT '區(qū)縣名稱',
`detail_address` STRING COMMENT '詳細(xì)地址',
`consignee` STRING COMMENT '收貨人',
`phone_num` STRING COMMENT '聯(lián)系電話',
`is_default` STRING COMMENT '是否默認(rèn)地址',
`create_time` DATETIME COMMENT '創(chuàng)建時間',
`operate_time` DATETIME COMMENT '操作時間',
`postal_code` STRING COMMENT '郵政編碼',
`full_address` STRING COMMENT '完整地址'
)
ENGINE=OLAP
UNIQUE KEY(`id`, `k1`)
DISTRIBUTED BY HASH(`id`);
4. ETL實(shí)現(xiàn)
-- 用戶域用戶地址全量表
INSERT INTO dwd.dwd_user_address_full(id, k1, user_id, province_id, province_name,
city_id, city_name, district_id, district_name, detail_address, consignee,
phone_num, is_default, create_time, operate_time, postal_code, full_address)
select
ua.id,
date('${pdate}') as k1, -- 使用參數(shù)日期作為k1值
ua.user_id,
ua.province_id,
bp.name as province_name,
ua.city_id,
bp.area_code as city_name, -- 這里假設(shè)使用area_code作為城市名稱,實(shí)際應(yīng)根據(jù)實(shí)際情況調(diào)整
ua.district_id,
bp.iso_code as district_name, -- 這里假設(shè)使用iso_code作為區(qū)域名稱,實(shí)際應(yīng)根據(jù)實(shí)際情況調(diào)整
ua.user_address as detail_address, -- 將user_address字段映射為detail_address
ua.consignee,
ua.phone_num,
ua.is_default,
now() as create_time, -- 使用當(dāng)前時間作為create_time
now() as operate_time, -- 使用當(dāng)前時間作為operate_time
null as postal_code, -- 暫無此數(shù)據(jù),可根據(jù)實(shí)際情況調(diào)整
concat(bp.name, ' ', bp.area_code, ' ', bp.iso_code, ' ', ua.user_address) as full_address -- 完整地址拼接
from
(
select
id,
user_id,
province_id,
province_id as city_id, -- 暫用province_id代替city_id
province_id as district_id, -- 暫用province_id代替district_id
user_address,
consignee,
phone_num,
is_default
from ods.ods_user_address_full
) ua
left join
(
select
id,
name,
area_code,
iso_code
from ods.ods_base_province_full
) bp
on ua.province_id = bp.id;
三、DWD層建設(shè)的經(jīng)驗(yàn)總結(jié)
- 統(tǒng)一規(guī)范先行:在開始建設(shè)前,制定統(tǒng)一的命名規(guī)范和數(shù)據(jù)標(biāo)準(zhǔn)
- 分階段建設(shè):先搭建核心業(yè)務(wù)域,后擴(kuò)展其他業(yè)務(wù)域
- 靈活處理數(shù)據(jù)缺失:面對不完美的數(shù)據(jù)源,使用合理的替代方案
- 重視文檔和注釋:詳細(xì)記錄表結(jié)構(gòu)、字段含義和處理邏輯
- 持續(xù)優(yōu)化:隨著業(yè)務(wù)發(fā)展,不斷完善DWD層數(shù)據(jù)模型