拉链表的实现过程

应用场景:

数据量大,且变化缓慢的维表,需要同时记录历史数据和最新的数据。
每天一份全量快照浪费存储空间,只保留最新的数据又无法覆盖全部业务场景,因此采用拉链表的方式进行存储。

数据变化场景:

1.当天新增
2.当天修改
3.当天删除
4.无变化
5.一天多跑

解决思路:

(使用数据生效的开始时间和结束时间来记录 数据的变化)
当天新增,直接添加新行,开始时间为当天,结束时间为极大值(9999-12-31)
当天修改,添加新行,修改旧行的结束时间为昨天
当天删除,修改结束时间
一天多跑,要和 “当天修改” 区分开来,开始时间和结束时间不变

解决方案:

  • 拉链表字段设置
  建立分区表dim_t_zip,
  添加开始时间start_date,结束时间end_date 
   ( 以结束时间作为分区字段,结束时间为‘9999-12-31’即为最新有效的数据,结束时间为昨天或过去的某一天,则为那一天的历史数据)
  添加删除标识del_flag,区分数据 是否已在业务端被删除
  • 具体步骤
  1. 取出拉链表中最新有效的数据放到tmp_old表中(过滤历史数据)
  2. 取出业务表当天更新的数据放到tmp_new表中
  3. 将新增的业务数据和拉链表的数据合并,tmp_old full join tmp_new ,为不同的数据变化场景打上标签,结果放到tmp_all
    1:当天新增数据(tmp_old.id is null)
    2:当天修改的数据(tmp_old.code !=tmp_new.code)
    3:无变化的数据
    4:源端已经删除的数据(tmp_new.id is null)
    5:一天多跑
  4. 将以下1,2,3分别取出后,union all 插入到tmp_result中
    1. (新增数据插入,修改前的旧行 修改结束时间,源端已删除是软删除,也算是最新有效)
      从tmp_all取出1,2,3,4场景的数据,如果是修改的数据,结束时间置为昨天,否则不变
    2. (添加修改后的数据,一天多跑场景的数据进行更新)
      从tmp_all 取出2,5场景的数据,join tmp_new ,如果是5场景,开始时间和结束时间不变,如果是2场景,开始时间和结束时间分别置为当天和极大值‘9999-12-31’
  5. 将tmp_result的数据,按照结束时间分区插到拉链表dim_t_zip中

代码实现

拉链(也称为单链)是一种常见的数据结构,在SQL中主要用于实现动态数组或者存储一些需要频繁插入和删除的数据。然而,SQL本身并不支持直接创建拉链结构,因为它是关系型数据库系统,设计用于处理格形式的数据。 但在数据库中,如果你需要类似的功能,可以使用以下步骤来模拟: 1. **创建节点**(如果数据库不支持自增长ID,还需要额外的标识列): ```sql CREATE TABLE Node ( id INT PRIMARY KEY, value VARCHAR(255), next_id INT, FOREIGN KEY (next_id) REFERENCES Node(id) ); ``` 2. **插入操作**:每次添加元素时,你可以向中添加一行,并记录下一个节点的ID(如果是第一个元素,`next_id`应为空): ```sql INSERT INTO Node (value, next_id) VALUES ('Value1', NULL); ``` 3. **链接操作**:为了连接两个节点,只需要更新其中一个节点的`next_id`指向新节点的`id`: ```sql UPDATE Node SET next_id = new_node_id WHERE id = old_node_id; ``` 4. **遍历操作**:虽然SQL本身不提供像链那样通过`current.next`访问下一项的功能,但可以通过递归查询或者编写程序语言(如PL/pgSQL等)来实现。 注意,这种做法并不是标准的链,而且效率相比其他专门的数据结构可能会低,因为它涉及到大量的关联操作。在实际数据库设计中,如果不是特别需要,通常会优先选择使用数组或索引来提高性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值