金融数据仓库系列-数据拉链

本文探讨数据仓库中四种常见表设计方法:全量表、增量表、拉链表及流水表,重点介绍拉链表的概念、作用及应用场景,旨在解决大数据量下的存储优化和历史数据查询需求。

在数据仓库的表设计通常会根据业务情况和源系统对数据的存储情况对仓库的表进行设计以便更好的利用存储资源和完成保留数据记录,通知表的设计分如下几种方法:

1. 全量表:每天的所有的最新状态的数据,缺点:浪费存储空间
2. 增量表:每天的新增数据,增量数据是上次导出之后的新数据。
3. 拉链表:维护历史状态,以及最新状态数据的一种表,拉链表根据拉链粒度的不同,实际上相当于快照,只不过做了优化,去除了一部分不变的记录而已,通过拉链表可以很方便的还原出拉链时点的客户记录。
4. 流水表: 对于表的每一个修改都会记录,可以用于反映实际记录的变更。 

什么是数据拉链?

拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。就是一张拉链表,存储的是用户的最基本信息以及每条记录的生命周期。

 

为什么要做数据拉链?

  • 1. 数据量比较大,在数据跑批的时候占用资源并且跑批时间过长,影响报表出数据等
  • 2. 表中的部分字段会被update,如用户电话号码、用户地址、账户余额等字段
  • 3. 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态,比如,查看某一个用户在过去某一段时间内,更新过几次等等;
  • 4. 变化的比例和频率不是很大,比如,总共一张5000万的客户信息表,只有不到200万的客户信息修改
  • 5. 如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费;
### 拉链表的实现原理与工作机制 拉链表(Slowly Changing Dimension Type 2,SCD Type 2)是一种用于数据仓库设计的技术,主要用于处理维度表中缓慢变化的属性。其核心目标是**记录数据的历史变化**,以便在分析时能够回溯到特定时间点的数据状态[^2]。 #### 数据变化的记录方式 拉链表通过引入两个额外的时间戳字段(通常为 `start_time` 和 `end_time`)来记录每条记录的有效时间范围。每当维度表中的某条记录发生变更时,系统不会直接更新原有记录,而是生成一条新记录,并更新时间戳字段以反映变更的时间点。原有记录的 `end_time` 被设置为变更发生的时间,而新记录的 `start_time` 与之对应,`end_time` 则设置为一个远未来的日期(例如 `9999-12-31`),表示该记录当前有效。 #### 数据存储的优化 在数据量较大的场景下,如果每天都保留全量数据快照,会导致存储资源的浪费。拉链表通过**仅记录发生变化的数据**,显著减少了存储开销。例如,一个拥有 1000 万会员的系统,每天只有 10 万条记录发生变化,使用拉链表可以避免重复存储 990 万条未变化的记录。 #### 数据查询的灵活性 拉链表支持对历史数据的多维度查询,用户可以: - 查询某一时间点的快照数据- 查询某条记录在特定时间段内的所有变更。 - 对比不同时间点的数据状态。 这种灵活性使得拉链表在需要**历史数据分析**的场景中表现优异,例如电商订单状态跟踪、金融客户信息变更记录等[^1]。 #### 拉链表的实现机制 实现拉链表通常涉及以下步骤: 1. **初始化拉链表**:将源数据表中的所有记录导入拉链表,并设置 `start_time` 为数据创建时间,`end_time` 为一个远未来的日期。 2. **检测数据变更**:通过对比源数据拉链表中的现有记录,识别出发生变化的字段。 3. **更新拉链表**: - 对于发生变化的记录,将原有记录的 `end_time` 设置为当前时间,并生成一条新记录,`start_time` 设置为当前时间,`end_time` 设置为远未来日期。 - 对于未发生变化的记录,不做任何修改。 4. **定期维护**:对拉链表进行索引优化和分区管理,以提升查询性能。 #### 示例代码(Hive 环境) 以下是一个基于 Hive 的拉链表实现示例: ```sql -- 创建拉链表 CREATE TABLE order_dim ( order_id STRING, customer_id STRING, order_status STRING, start_time TIMESTAMP, end_time TIMESTAMP ) PARTITIONED BY (dt STRING) STORED AS ORC; -- 插入初始数据 INSERT INTO TABLE order_dim PARTITION (dt='2023-10-01') SELECT order_id, customer_id, order_status, '2023-10-01 00:00:00' AS start_time, '9999-12-31 23:59:59' AS end_time FROM initial_order_data; -- 更新拉链表 WITH updated_data AS ( SELECT o.order_id, o.customer_id, o.order_status, CASE WHEN o.order_status != d.order_status THEN '2023-10-02 00:00:00' ELSE d.start_time END AS new_start_time, CASE WHEN o.order_status != d.order_status THEN '9999-12-31 23:59:59' ELSE d.end_time END AS new_end_time, d.start_time AS old_start_time, d.end_time AS old_end_time FROM current_order_data o LEFT JOIN order_dim d ON o.order_id = d.order_id AND d.end_time = '9999-12-31 23:59:59' ) -- 更新原有记录的 end_time UPDATE order_dim SET end_time = '2023-10-02 00:00:00' WHERE order_id IN (SELECT order_id FROM updated_data WHERE order_status != old_order_status); -- 插入新记录 INSERT INTO TABLE order_dim PARTITION (dt='2023-10-02') SELECT order_id, customer_id, order_status, new_start_time, new_end_time FROM updated_data; ``` #### 拉链表的优缺点 **优点**: - **历史记录完整**:能够完整记录数据的历史变化。 - **节省存储空间**:相比全量快照,拉链表仅记录变化数据,减少存储开销。 - **支持时间点查询**:便于分析特定时间点的数据状态[^2]。 **缺点**: - **实现复杂**:需要处理时间戳的更新逻辑和数据对比。 - **查询性能下降**:由于数据量增加,查询性能可能受到影响。 - **维护成本高**:需要定期进行索引优化和分区管理。 #### 拉链表与其他表的对比 - **与切片表对比**:切片表通常记录某一时间点的快照,而拉链表记录数据的完整生命周期。 - **与流水表对比**:流水表记录所有操作(如插入、更新、删除),而拉链表仅记录维度表中缓慢变化的字段[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值