暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 增加主键列

生有可恋 2022-04-08
1090

业务人员要求在一个表上重新创建主键列。表中已有的数据存在重复,需要对每一行数据生成唯一值作为主键。

首先想到的方法创建一个临时表,通过 rowid 与原表建立关联,然后根据临时表对原表进行更新。

临时表建表语句为

    create table met_ipm_order_tmp as
    select ROWIDTOCHAR(t.rowid) as primary_key from met_ipm_order t;

    更新语句为

      UPDATE met_ipm_order t
         SET t.id =       
             (
      SELECT t.primary_key
                FROM met_ipm_order_tmp p
               WHERE t.rowid = p.primary_key
              )
       WHERE EXISTS (
      SELECT 1 FROM met_ipm_order_tmp p
              WHERE t.rowid = p.primary_key
      );

      因为业务只要求主键列数据唯一,对内容没有要求,所以直接使用 rowid 作为主键。如果想使用数字作为主键,可以使用 rownum 作为主键。

      在测试库执行时发现,表的数据量非常大,记录数有5千万条,没法通过一条 update 对全表进行更新。如果在实际业务中,这种更新将无法实施,因为表处于活跃状态,并且读写非常频繁,大数据量更新,在业务高峰时将造成锁表。

      于是放弃 update 方案,尝试使用小步更新方式来写入数据。最终在测试库中的尝试的方案是使用 ETL 工具 Spoon ,辅助临时表对目标表执行 update。ETL 工具有小批量更新的机制,不会造成长时间锁表,但执行时间会拖的比较长。

      最后一个方案是在CSDN上查到的,基于 sequence 更新,也是全表update。我在测试库上试了一下,执行速度要比临时表方式要快一点儿。

        -- 增加主键列
        alter table met_ipm_order add pk_id number(38);

        create sequence MET_IPM_SEQ_ID
        minvalue 1
        maxvalue 999999999
        start with 1;

        Update met_ipm_order set pk_id=MET_IPM_SEQ_ID.nextval;

        commit;

        参考:

        • https://blog.csdn.net/lexang1/article/details/73900034

        文章转载自生有可恋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论