关于拉链表

本文详细介绍了拉链表技术在数据仓库中的应用,包括其概念、算法实现及一个具体实例,通过对比历史表与当日全量数据,阐述了如何高效地记录和更新客户状态信息。

(一)概念
      拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。

 

      在历史表中对客户的一生的记录可能就这样几条记录,避免了按每一天记录客户状态造成的海量存储的问题:
(NAME)人名 (START-DATE)开始日期 (END-DT)结束日期 (STAT)状态
     client              19000101                         19070901                H在家
     client              19070901                         19130901                A小学
     client              19130901                         19160901                B初中
     client              19160901                         19190901                C高中
     client              19190901                         19230901                D大学
     client              19230901                         19601231                E公司
     client              19601231                         29991231             H退休在家

 

     上面的每一条记录都是不算末尾的,比如到19070901,client已经在A,而不是H了。所以除最后一条记录因为状态到目前都未改变的,其余的记录实际上在END-DT那天,都不在是该条记录END-DT那天的状态。这种现象可以理解为算头不算尾。


(二)算法
     1、采集当日全量数据到ND(NewDay)表;
     2、可从历史表中取出昨日全量数据存储到OD(OldDay)表;
     3、(ND-OD)就是当日新增和变化的数据,也就是当天的增量,用W_I表示;
     4、(OD-ND)为状态到此结束需要封链的数据,用W_U表示;

     5、将W_I表的内容全部插入到历史表中,这些是新增记录,start_date为当天,而end_date为max值;
     6、对历史表进行W_U部份的更新操作,start_date保持不变,而end_date改为当天,也就是关链操作;


(三)一个实际例子(teradata)
     1、定义两个临时表,一个为当日全量数据,另一个为需要新增或更新的数据;
     CREATE VOLATILE TABLE VT_xxxx_NEW AS xxxx WITH NO DATA ON COMMIT PRESERVE ROWS;
     CREATE VOLATILE SET TABLE VT_xxxx_CHG,NO LOG AS xxxx WITH NO DATA ON COMMIT PRESERVE ROWS;

 

     2、获取当日全量数据
     INSERT INTO VT_xxxx_NEW(xx) SELECT (xx,cur_date, max_date) FROM xxxx_sorce; ND

 

     3、抽取新增或有变化的数据,从xxxx_NEW临时表到xxxx_CHG临时表;
     INSERT INTO VT_xxxx_CHG(xx)
     SELECT xx FROM VT_xxxx_NEW
     WHERE (xx) NOT IN (select xx from xxxx_HIS where end_date='max_date');

 

     4、更新历史表的失效记录的end_date为max值
     UPDATE A1 FROM xxxx_HIS A1, VT_xxxx_CHG A2
     SET End_Date='current_date'
     WHERE A1.xx=A2.xx AND A1.End_Date='max_date';
     5、将新增或者有变化的数据插入目标表*/
     INSERT INTO xxxx_HIS SELECT * FROM VT_xxxx_CHG;

### 关于拉链查询历史快照的实现 #### 拉链的概念 拉链是一种常见的数据仓库建模技术,主要用于记录维度中每一行的有效期范围。通过这种方式可以追踪每一条记录的历史变化情况。通常情况下,拉链会包含以下几个字段:`主键`、`属性列`、`生效时间(start_date)` `失效时间(end_date)`[^2]。 #### 查询历史快照的方法 为了查询某个特定时间点的数据状态,可以通过 SQL 的过滤条件来限定有效期内的记录。具体来说,对于给定的时间戳 `T`,只需要筛选满足以下条件的记录即可: - 记录的 `start_date <= T` - 记录的 `end_date > T` 这种查询方式能够确保返回的结果是在指定时间范围内有效的数据版本。 以下是具体的 SQL 示例: ```sql SELECT * FROM chain_table WHERE '2023-10-01' BETWEEN start_date AND end_date; ``` 上述代码片段展示了如何查询 2023 年 10 月 1 日当天处于有效期内的所有记录。 #### Flink 中的拉链应用 在实际项目中,如果使用 Apache Flink 进行实时数仓构建,则可能涉及 MySQL 数据库中的 Binlog 同步过程。按照引用描述,在此场景下,Flink 可能先将全量数据写入快照,再逐步更新流水并最终定期合并生成新的拉链结构[^3]。 下面是一个简单的 Python 脚本示例,用于模拟创建维护拉链的过程: ```python import pandas as pd def update_chain_table(chain_df, new_data): """ 更新现有的拉链。 :param chain_df: 当前的拉链 DataFrame :param new_data: 新增/修改后的数据列 [{'id': ..., 'attr': ..., 'update_time': ...}] :return: 更新后的拉链 DataFrame """ updated_records = [] current_time = pd.Timestamp.now() for record in new_data: id_ = record['id'] # 查找当前 ID 是否已存在于拉链中 existing_record = chain_df[(chain_df['id'] == id_) & (chain_df['end_date'] == pd.to_datetime('9999-12-31'))] if not existing_record.empty: # 如果存在未结束的记录,则关闭该条目 idx_to_close = existing_record.index[0] chain_df.at[idx_to_close, 'end_date'] = current_time # 插入新记录 updated_records.append({ 'id': id_, 'attribute': record['attr'], 'start_date': current_time, 'end_date': pd.to_datetime('9999-12-31') }) # 将新增加的内容追加到原始格上 return pd.concat([chain_df, pd.DataFrame(updated_records)], ignore_index=True) # 初始化一个空的拉链 initial_chain_table = pd.DataFrame(columns=['id', 'attribute', 'start_date', 'end_date']) # 添加一些测试数据 new_entries = [ {'id': 1, 'attr': 'value_a', 'update_time': None}, {'id': 2, 'attr': 'value_b', 'update_time': None} ] updated_chain_table = update_chain_table(initial_chain_table, new_entries) print(updated_chain_table) ``` 以上脚本演示了如何动态管理拉链,并支持随着时间推移不断加入最新版次的信息。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值