9.数据仓库搭建之DIM层搭建

本文详细介绍了数据仓库中DIM层的搭建过程,包括商品、用户、地区、优惠券、活动和日期等六个维度的确定、维度表设计、数据装载逻辑,以及首日和每日装载脚本的编写。DIM层采用orc列式存储+snappy压缩,遵循特定命名规范。

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

数据仓库搭建之DIM层搭建

在开发数据仓库的DIM层时,我们需要注意以下几点:

1)DIM层的设计依据是维度建模理论,该层存储维度模型的维度表。

2)在我们该项目当中,DIM层的数据存储格式为orc列式存储+snappy压缩。

3)DIM层表名的命名规范为dim_表名_全量表或者拉链表标识(full/zip)。

1.维度确定

我们根据之前构建的业务总线矩阵,来确定我们当前需要构建的维度表。


我们可以看到,我们所有的业务过程所涉及到的维度有时间、用户、商品、地区、活动、优惠券、支付方式、退单类型、退单原因类型、渠道以及设备。

虽然有这么多的维度,但是我们并不会将这些维度都构建成维度表。但是我们考虑到维度退化,一些维度中字段比较少,较为简单,因此我们将该维度中的字段退化到与之对应的事实表当中。

因此,我们最终选择的维度有时间、用户、商品、地区、活动和优惠券共六个维度。

2.维度表设计

2.1商品维度表

2.1.1确定维度

这里的维度已经确定,是商品维度

2.1.2确定主维表和相关维表

此处的主维表和相关维表均指电商业务系统中与某维度相关的表。

在这里插入图片描述

由于我们表中的字段有部分冗余(为了提高查询的速度),因此我们最终的主维表和相关维表如下图所示(图中有颜色的是最终的主维表和相关维表):
在这里插入图片描述

2.1.3确定维度属性
DROP TABLE IF EXISTS dim_sku_full;
CREATE EXTERNAL TABLE dim_sku_full
(
    `id`                   STRING COMMENT 'sku_id',
    `price`                DECIMAL(16, 2) COMMENT '商品价格',
    `sku_name`             STRING COMMENT '商品名称',
    `sku_desc`             STRING COMMENT '商品描述',
    `weight`               DECIMAL(16, 2) COMMENT '重量',
    `is_sale`              BOOLEAN COMMENT '是否在售',
    `spu_id`               STRING COMMENT 'spu编号',
    `spu_name`             STRING COMMENT 'spu名称',
    `category3_id`         STRING COMMENT '三级分类id',
    `category3_name`       STRING COMMENT '三级分类名称',
    `category2_id`         STRING COMMENT '二级分类id',
    `category2_name`       STRING COMMENT '二级分类名称',
    `category1_id`         STRING COMMENT '一级分类id',
    `category1_name`       STRING COMMENT '一级分类名称',
    `tm_id`                STRING COMMENT '品牌id',
    `tm_name`              STRING COMMENT '品牌名称',
    `sku_attr_values`      ARRAY<STRUCT<attr_id :STRING,value_id :STRING,attr_name :STRING,value_name:STRING>> COMMENT '平台属性',
    `sku_sale_attr_values` ARRAY<STRUCT<sale_attr_id :STRING,sale_attr_value_id :STRING,sale_attr_name :STRING,sale_attr_value_name:STRING>> COMMENT '销售属性',
    `create_time`          STRING COMMENT '创建时间'
) COMMENT '商品维度表'
    PARTITIONED BY (`dt` STRING)
    STORED AS ORC
    LOCATION '/warehouse/gmall/dim/dim_sku_full/'
    TBLPROPERTIES ('orc.compress' = 'snappy');
2.1.4数据的装载逻辑(以2022-05-01为例)

我们需要从每一个表当中取出需要的数据,之后再通过join连接起来。

(1)sku_info表

select
        id,
        price,
        sku_name,
        sku_desc,
        weight,
        is_sale,
        spu_id,
        category3_id,
        tm_id,
        create_time
    from ods_sku_info_full
    where dt='2022-05-01'

(2)spu_info表

select
	id,
	spu_name
from ods_spu_info_full
where dt='2022-05-01'

(3)base_caregory3表

select
	id,
	name,
	category2_id
from ods_base_category3_full
where dt='2022-05-01'

(3)base_caregory2表

select
	id,
	name,	
	category1_id
from ods_base_category2_full
where dt='2022-05-01'

(4)base_caregory1表

select
	id,
	name
from ods_base_category1_full
where dt='2022-05-01'

(5)base_trademark表

select
	id,
	tm_name
from ods_base_trademark_full
where dt='2022-05-01'

(6)sku_attr_value表

select
	sku_id,  		collect_set(named_struct('attr_id',attr_id,'value_id',value_id,'attr_name',attr_name,'value_name',value_name)) attrs
from ods_sku_attr_value_full
where dt='2022-05-01'
group by sku_id

(7)sku_sale_attr_value表

select
	sku_id,     collect_set(named_struct('sale_attr_id',sale_attr_id,'sale_attr_value_id',sale_attr_value_id,'sale_attr_name',sale_attr_name,'sale_attr_value_name',sale_attr_value_name)) sale_attrs
from ods_sku_sale_attr_value_full
where dt='2022-05-01'
group by sku_id

最终,我们将上述从表中取到的数据进行join,然后装载到该商品维度表当中:

with
sku as
(
    select
        id,
        price,
        sku_name,
        sku_desc,
        weight,
        is_sale,
        spu_id,
        category3_id,
        tm_id,
        create_time
    from ods_sku_info_full
    where dt='2022-05-01'
),
spu as
(
    select
        id,
        spu_name
    from ods_spu_info_full
    where dt='2022-05-01'
),
c3 as
(
    select
        id,
        name,
        category2_id
    from ods_base_category3_full
    where dt='2022-05-01'
),
c2 as
(
    select
        id,
        name,
        category1_id
    from ods_base_category2_full
    where dt='2022-05-01'
),
c1 as
(
    select
        id,
        name
    from ods_base_category1_full
    where dt='2022-05-01'
),
tm as
(
    select
        id,
        tm_name
    from ods_base_trademark_full
    where dt='2022-05-01'
),
attr as
(
    select
        sku_id,
        collect_set(named_struct('attr_id',attr_id,'value_id',value_id,'attr_name',attr_name,'value_name',value_name)) attrs
    from ods_sku_attr_value_full
    where dt='2022-05-01'
    group by sku_id
),
sale_attr as
(
    select
        sku_id,
        collect_set(named_struct('sale_attr_id',sale_attr_id,'sale_attr_value_id',sale_attr_value_id,'sale_attr_name',sale_attr_name,'sale_attr_value_name',sale_attr_value_name)) sale_attrs
    from ods_sku_sale_attr_value_full
    where dt='2022-05-01'
    group by sku_id
)
insert overwrite table dim_sku_full partition(dt='2022-05-01')
select
    sku.id,
    sku.price,
    sku.sku_name,
    sku.sku_desc,
    sku.weight,
    sku.is_sale,
    sku.spu_id,
    spu.spu_name,
    sku.category3_id,
    c3.name,
    c3.category2_id,
    c2.name,
    c2.category1_id,
    c1.name,
    sku.tm_id,
    tm.tm_name,
    attr.attrs,
    sale_attr.sale_attrs,
    sku.create_time
from sku
left join spu on sku.spu_id=spu.id
left join c3 on sku.category3_id=c3.id
left join c2 on c3.category2_id=c2.id
left join c1 on c2.category1_id=c1.id
left join tm on sku.tm_id=tm.id
left join attr on sku.id=attr.sku_id
left join sale_attr on sku.id=sale_attr.sku_id;

2.2用户维度表

2.2.1确定维度

这里的维度已经确定,是用户维度

2.2.2确定主维表和相关维表

此处的主维表和相关维表均指电商业务系统中与某维度相关的表。

在这里插入图片描述

我们最终只选择user_info一张表作为用户维度的主维表,因为我们对用户的地址表不经常使用,因此此处不添加用户地址表进行join。

2.2.3确定维度属性
DROP TABLE IF EXISTS dim_user_zip;
CREATE EXTERNAL TABLE dim_user_zip
(
    `id`           STRING COMMENT '用户id',
    `login_name`   STRING COMMENT '用户名称',
    `nick_name`    STRING COMMENT '用户昵称',
    `name`         STRING COMMENT '用户姓名',
    `phone_num`    STRING COMMENT '手机号码',
    `email`        STRING COMMENT '邮箱',
    `user_level`   STRING COMMENT '用户等级',
    `birthday`     STRING COMMENT '生日',
    `gender`       STRING COMMENT '性别',
    `create_time`  STRING COMMENT '创建时间',
    `operate_time` STRING COMMENT '操作时间',
    `start_date`   STRING COMMENT '开始日期',
    `end_date`     STRING COMMENT '结束日期'
) COMMENT '用户表'
    PARTITIONED BY (`dt` STRING)
    STORED AS ORC
    LOCATION '/warehouse/gmall/dim/dim_user_zip/'
    TBLPROPERTIES ('orc.compress' = 'snappy');
2.2.4数据的分区规划

拉链表的意义就在于能够更加高效的保存维度信息的历史状态。拉链表适合于数据会发生变化,但是变化频率并不高的维度(缓慢变化维)。因此,我们的用户维度表设计为拉链表,因为每天变化的比例并不高。

我们的数据分区规划如下所示:

在这里插入图片描述

我们将全量最新的用户数据存储到dt=9999-12-31分区当中。

2.2.4数据装载
2.2.4.1拉链表数据装载过程

在这里插入图片描述

2.2.4.3拉链表数据流向

在这里插入图片描述

2.2.4.4用户维表首日装载(以2022-05-01作为首日)

用户的首日装载较为简单,即装载全量的数据:

insert overwrite table dim_user_zip partition (dt='9999-12-31')
select
    data.id,
    data.login_name,
    data.nick_name,
    md5(data.name),
    md5(data.phone_num),
    md5(data.email),
    data.user_level,
    data.birthday,
    data.gender,
    data.create_time,
    data.operate_time,
    '2022-05-01' start_date,
    '9999-12-31' end_date
from ods_user_info_inc
where dt='2022-05-01'
and type='bootstrap-insert';
2.2.4.5用户维表每日装载

(1)用户维度表每日装载思路

在这里插入图片描述

(2)具体装载语句

with
tmp as
(
    select
        old.id old_id,
        old.login_name old_login_name,
        old.nick_name old_nick_name,
        old.name old_name,
        old.phone_num old_phone_num,
        old.email old_email,
        old.user_level old_user_level,
        old.birthday old_birthday,
        old.gender old_gender,
        old.create_time old_create_time,
        old.operate_time old_operate_time,
        old.start_date old_start_date,
        old.end_date old_end_date,
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值