Oracle拉链表

什么是拉链表?

简单点说:记录一个事物,从开始一直到当前状态的所有变化信息。
复杂点说:记录数据在某一时间内的状态,以及数据在某一时间点的变化的数据存储方式。

为什么需要拉链表?

针对一些数据量大的表,像是保存了几年的数据,但是新增或者需要操作查看的数据只有一部分,或者只需要某个时间节点的数据,这个时候就可以使用拉链表进行操作。

怎么编写拉链表代码?

  1. 创建一个拷贝了emp的临时表emp1,防止修改到emp源表。
  	   drop table emp1;--如果以前有
       alter table emp1 add up_date date; --添加了一个新增数据的时间节点字段
       insert into emp1 e1(
          e1.empno,
          e1.ename,
          e1.job,
          e1.mgr,
          e1.hiredate,
          e1.sal,
          e1.comm,
          e1.deptno,
          e1.up_date
          )
          select 
          et.empno,
          et.ename,
          et.job,
          et.mgr,
          et.hiredate,
          et.sal,
          et.comm,
          et.deptno,
          sysdate-5
       from emp et;
       select * from emp1
  1. 创建目标表,用来比对emp1的数据
    重要字段start_date 、end_date 主要是这两个字段提取一段时间的数据。
---目标表
 drop table linkTable;
 create table linkTable as select * from emp where 1=2;
 select * from linkTable;
 alter table linkTable add up_date date;
 alter table linkTable add start_date date;--开始时间
 alter table linkTable add end_date date;--结束时间
 
 insert into linkTable lt(
        lt.empno,
        lt.ename,
        lt.job,
        lt.mgr,
        lt.hiredate,
        lt.sal,
        lt.comm,
        lt.deptno,
        lt.up_date,
        lt.start_date,
        lt.end_date
       
 )
        select 
          et.empno,
          et.ename,
          et.job,
          et.mgr,
          et.hiredate,
          et.sal,
          et.comm,
          et.deptno,
          et.up_date,
          to_date('2024-4-26','YYYY-MM-DD'),
          to_date('9999-9-9','YYYY-DD-MM')
        from emp1 et;
        
  1. 手动模拟新增的emp1数据
 update emp1 set sal=sal+1000,up_date=sysdate where ename='SMITH';
 insert into emp1 values(9999,'张三','xingjiapo',7369,
 				  date'1998-06-01',3600,1000,10,sysdate-1);
 select * from emp1;
 
  1. 创建一个存储过程,封装更新数据的动作。
    开链:目标中没有改记录,新增插入该条记录并把结束时间改成无穷大。
    闭链:目标中存在该条记录,只是部分状态值不同,update该数据,并把end_date调整为当日时间。
 ---创建存储过程
        create or replace procedure updateLinkTable(startTime varchar2,endTime varchar2)
        is
        v_start date := to_date(startTime,'YYYY-MM-DD HH24:MI:SS');
        v_end date := to_date(endTime,'YYYY-MM-DD HH24:MI:SS');
        cursor update_cursor is --创建游标保存指定时间内需要比对的数据
        select * from emp1  
        where up_date>=v_start and up_date<=v_end; ---指定时间内的数据
        v_count number;
        begin 
          for i in update_cursor loop --目标表与源表比对,
            select count(1) into v_count from linkTable lk --找到当前的数据并且当前数据未过期
            where i.empno = lk.empno and lk.end_date=to_date('9999-9-9','YYYY-MM-DD');
            
            if v_count=1 then
               update linkTable lk set lk.end_date=trunc(sysdate-1) --把原先的数据更新为过期数据(历史数据) 也就是闭链
               where i.empno = lk.empno and lk.end_date=to_date('9999-9-9','YYYY-MM-DD');
               --添加当前已更新的业务变动数据,并更新end_date无穷大
               insert into linkTable lk(
                      lk.empno,
                      lk.ename,
                      lk.job,
                      lk.mgr,
                      lk.hiredate,
                      lk.sal,
                      lk.comm,
                      lk.deptno,
                      lk.up_date,
                      lk.start_date,
                      lk.end_date
               ) values(
                      i.empno,
                      i.ename,
                      i.job,
                      i.mgr,
                      i.hiredate,
                      i.sal,
                      i.comm,
                      i.deptno,
                      i.up_date,
                      trunc(sysdate),
                      to_date('9999-9-9','YYYY-MM-DD')
               );
               elsif v_count=0 then --没有匹配上说明当前数据是新增数据,直接插入进去即可 (更新end_date无穷大 开链)
                  insert into linkTable lk(
                      lk.empno,
                      lk.ename,
                      lk.job,
                      lk.mgr,
                      lk.hiredate,
                      lk.sal,
                      lk.comm,
                      lk.deptno,
                      lk.up_date,
                      lk.start_date,
                      lk.end_date
               ) values(
                      i.empno,
                      i.ename,
                      i.job,
                      i.mgr,
                      i.hiredate,
                      i.sal,
                      i.comm,
                      i.deptno,
                      i.up_date,
                      trunc(sysdate),
                      to_date('9999-9-9','YYYY-MM-DD')
               );
            end if;
          end loop;
            exception
              when others then
                dbms_output.put_line(sqlcode);
                dbms_output.put_line(sqlerrm);
        end;
        
        select * from linkTable;
        select * from emp1;
  1. 调用存储过程,更新指定时间数据。
 ---方法一 pl/sql调用
begin
updateLinkTable('2024-5-28  00:00:00','2024-5-29 23:59:59');
end;
--方法二 SQL语句调用
call updateLinkTable(p_star => '2024-05-28 00:00:00',p_end => '2024-05-29 23:59:59');
-- 或者
call updateLinkTable('2024-05-28 00:00:00','2024-05-29 23:59:59');

拉链表的优缺点

优点

  • 节省存储空间,避免没必要的重复数据
  • 能查询到历史快照

缺点

  • 内存占用,查询效率受拉链长度的影响
  • 断链难以恢复

相关推荐

  1. Oracle拉链

    2024-06-05 20:00:03       30 阅读
  2. 数据仓库之拉链

    2024-06-05 20:00:03       26 阅读
  3. Hive 拉链详解及实例

    2024-06-05 20:00:03       47 阅读
  4. 拉链的概念设计与实现

    2024-06-05 20:00:03       52 阅读
  5. 缓慢渐变维与拉链

    2024-06-05 20:00:03       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-05 20:00:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-05 20:00:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-05 20:00:03       87 阅读
  4. Python语言-面向对象

    2024-06-05 20:00:03       96 阅读

热门阅读

  1. PostgreSQL 和Oracle锁机制对比

    2024-06-05 20:00:03       33 阅读
  2. Neo4J中构建的知识图谱,如何使用推理算法

    2024-06-05 20:00:03       32 阅读
  3. EasyExcel实现导入导出

    2024-06-05 20:00:03       25 阅读
  4. QT常用快捷键

    2024-06-05 20:00:03       31 阅读
  5. 华为欧拉 openEuler 23.09 一键安装 Oracle 12CR2 单机

    2024-06-05 20:00:03       28 阅读
  6. go语言进阶 包

    2024-06-05 20:00:03       28 阅读
  7. [12] 使用 CUDA 加速排序算法

    2024-06-05 20:00:03       28 阅读
  8. 将vector/array从非托管c++传递到c#

    2024-06-05 20:00:03       34 阅读
  9. ubuntu使用Docker笔记

    2024-06-05 20:00:03       35 阅读
  10. 升级Jenkins从2.263.3到2.440.2

    2024-06-05 20:00:03       39 阅读
  11. 贪心算法和动态规划算法选择依据

    2024-06-05 20:00:03       30 阅读