用户维度表(拉链表)

步骤0:初始化拉链表(首次独立执行)
(1)建立拉链表
hive (gmall)>
drop table if exists dwd_dim_user_info_his;
create external table dwd_dim_user_info_his(
id string COMMENT ‘用户id’,
name string COMMENT ‘姓名’,
birthday string COMMENT ‘生日’,
gender string COMMENT ‘性别’,
email string COMMENT ‘邮箱’,
user_level string COMMENT ‘用户等级’,
create_time string COMMENT ‘创建时间’,
operate_time string COMMENT ‘操作时间’,
start_date string COMMENT ‘有效开始日期’,
end_date string COMMENT ‘有效结束日期’
) COMMENT ‘用户拉链表’
stored as parquet
location ‘/warehouse/gmall/dwd/dwd_dim_user_info_his/’
tblproperties (“parquet.compression”=“lzo”);

(2)初始化拉链表
hive (gmall)>
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
insert overwrite table dwd_dim_user_info_his
select
id,
name,
birthday,
gender,
email,
user_level,
create_time,
operate_time,
‘2020-06-14’,
‘9999-99-99’
from ods_user_info oi
where oi.dt=‘2020-06-14’;

步骤1:制作当日变动数据(包括新增,修改)每日执行
(1)如何获得每日变动表
a.最好表内有创建时间和变动时间(Lucky!)
b.如果没有,可以利用第三方工具监控比如canal,监控MySQL的实时变化进行记录(麻烦)。
c.逐行对比前后两天的数据,检查md5(concat(全部有可能变化的字段))是否相同(low)
d.要求业务数据库提供变动流水(人品,颜值)
(2)因为ods_user_info本身导入过来就是新增变动明细的表,所以不用处理
a)数据库中新增2020-06-15一天的数据
b)通过Sqoop把2020-06-15日所有数据导入
mysql_to_hdfs.sh all 2020-06-15
c)ods层数据导入
hdfs_to_ods_db.sh all 2020-06-15

步骤2:先合并变动信息,再追加新增信息,插入到临时表中
1)建立临时表
hive (gmall)>
drop table if exists dwd_dim_user_info_his_tmp;
create external table dwd_dim_user_info_his_tmp(
id string COMMENT ‘用户id’,
name string COMMENT ‘姓名’,
birthday string COMMENT ‘生日’,
gender string COMMENT ‘性别’,
email string COMMENT ‘邮箱’,
user_level string COMMENT ‘用户等级’,
create_time string COMMENT ‘创建时间’,
operate_time string COMMENT ‘操作时间’,
start_date string COMMENT ‘有效开始日期’,
end_date string COMMENT ‘有效结束日期’
) COMMENT ‘订单拉链临时表’
stored as parquet
location ‘/warehouse/gmall/dwd/dwd_dim_user_info_his_tmp/’
tblproperties (“parquet.compression”=“lzo”);
2)导入脚本
hive (gmall)>
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
insert overwrite table dwd_dim_user_info_his_tmp
select * from
(
select
id,
name,
birthday,
gender,
email,
user_level,
create_time,
operate_time,
‘2020-06-15’ start_date,
‘9999-99-99’ end_date
from ods_user_info where dt=‘2020-06-15’

union all 
select 
    uh.id,
    uh.name,
    uh.birthday,
    uh.gender,
    uh.email,
    uh.user_level,
    uh.create_time,
    uh.operate_time,
    uh.start_date,
    if(ui.id is not null  and uh.end_date='9999-99-99', date_add(ui.dt,-1), uh.end_date) end_date
from dwd_dim_user_info_his uh left join 
(
    select
        *
    from ods_user_info
    where dt='2020-06-15'
) ui on uh.id=ui.id

)his
order by his.id, start_date;

步骤3:把临时表覆盖给拉链表
1)导入数据
hive (gmall)>
insert overwrite table dwd_dim_user_info_his
select * from dwd_dim_user_info_his_tmp;
2)查询导入数据
hive (gmall)>
select id, start_date, end_date from dwd_dim_user_info_his limit 2;

### 拉链的概念 拉链是一种用于维护历史状态和最新状态的数据结构,其核心在于通过时间范围来示每条记录的有效期。具体来说,拉链中的每一行数据都包含了两个时间字段:`start_date` 和 `end_date`,分别代该记录的生效时间和失效时间[^1]。 这种设计使得拉链能够高效地存储变化的历史数据,并支持快速查询某一时点的状态快照。相比传统的全量备份方式,拉链通过对未发生变化的记录进行去重处理,从而节省了存储空间并提高了性能。 --- ### 拉链的使用场景 拉链广泛应用于数据仓库领域,尤其是在需要追踪实体变更历史的情况下。例如,在客户管理、产品信息更新或员工档案变动等业务场景中,可以通过拉链轻松获取任意时刻的特定版本数据[^2]。 #### 查询示例 假设有一个名为 `user` 的拉链,其中包含用户的姓名 (`name`)、地址 (`address`) 及有效时间段 (`t_start_date`, `t_end_date`)。如果要查询 2017 年 1 月 2 日的历史快照,SQL 查询语句可写为: ```sql SELECT * FROM user WHERE t_start_date <= '2017-01-02' AND t_end_date >= '2017-01-02'; ``` 此查询返回的结果将是所有在指定日期范围内有效的用户记录[^2]。 --- ### 拉链的设计与实现 以下是基于 Hive 的一个典型例子,展示如何构建一张简单的拉链。假设有如下原始维度 `customer_dim`: | customer_id | name | address | start_date | end_date | is_current | |-------------|------------|------------|------------|------------|------------| | 1 | John Doe | Address 1 | 2020-01-01 | 2021-01-01 | 0 | | 1 | John Doe | Address 2 | 2021-01-01 | 9999-12-31 | 1 | 在此中: - `start_date` 示当前记录何时开始生效; - `end_date` 示当前记录何时结束(通常用特殊值如 `'9999-12-31'` 来标记最新的活动记录); - `is_current` 是一个标志位,用来区分当前活跃记录与其他已过期记录[^3]。 当客户的某些属性发生更改时,旧记录会被设置新的 `end_date`,而新记录则会插入到中,继承相同的 `customer_id`,同时赋予一个新的 `start_date` 和默认的最大 `end_date`。 --- ### 实现步骤概述 虽然不允许使用步骤词汇描述过程,但仍可通过逻辑顺序说明其实现机制。首先定义初始状态下的基础数据集;其次每当检测到目标对象有修改动作时,需调整原有关联的时间区间参数以反映实际改动情况;最后将新增加的信息按照既定规则补充至数据库之中完成整个流程闭环操作[^3]。 --- ### 示例代码 以下是一个 Python 脚本模拟创建简单版拉链的过程: ```python from datetime import datetime, timedelta class CustomerRecord: def __init__(self, id_, name, address, start_date=None, end_date='9999-12-31'): self.id_ = id_ self.name = name self.address = address self.start_date = start_date or str(datetime.now().date()) self.end_date = end_date def update_record(records, new_data): updated_records = [] for record in records[:]: if record.id_ == new_data['id']: # Update existing record's end date to today minus one day yesterday = (datetime.strptime(new_data['start_date'], '%Y-%m-%d') - timedelta(days=1)).strftime('%Y-%m-%d') record.end_date = yesterday # Add the old version back into list with adjusted dates updated_records.append(record) # Insert the new data as a fresh entry updated_records.append(CustomerRecord(**new_data)) return updated_records # Example usage initial_records = [ CustomerRecord(1, "John Doe", "Address 1"), ] updated_records = update_record(initial_records, { 'id': 1, 'name': 'John Doe', 'address': 'Address 2', 'start_date': '2021-01-01' }) for r in updated_records: print(f"{r.id_}, {r.name}, {r.address}, {r.start_date}, {r.end_date}") ``` 上述脚本展示了如何动态维护一条顾客记录的变化历程。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值