【问题标题】:Populate newly created columns for older database records in production?为生产中的旧数据库记录填充新创建的列?
【发布时间】:2020-06-15 22:52:02
【问题描述】:

我偶然发现了一个我认为很常见但我不经常听到的场景。

所以,我有一种情况,我用另一列扩展了我现有的数据库表,该列应该为每个客户存储非常具体的唯一值。当我在系统中创建新记录时,该列将被填充并且工作正常。 但是,现在的问题是,我有一堆在介绍本专栏之前就存在的旧记录,它们是空的,因此代码无法正确执行。

我真的很好奇这个问题通常是如何解决的?为了用有效值填充此列,我唯一的解决方案是运行一个脚本,该脚本将从一个表中提取值并将其插入另一个表中,但是否有更标准化的解决方案?

我正在使用 spring boot 和 flyway 进行数据库迁移,如果有相关的解决方案会很棒。

【问题讨论】:

    标签: spring spring-boot flyway


    【解决方案1】:

    当这种情况发生时,我只是制作了一个新版本的 flyway 迁移包,例如:

     migration/V4__add_column1_table1
     migration/V5__fix_table1_column1_nulls
    

    在脚本内部运行:

    update table1 set column1 = 'Default Value' where column1 is null;
    

    也许存在更干净的方法,但该修​​复对我有用。

    【讨论】:

    • 我可以这样做,但在我的情况下,“默认值”不会让我走得太远,我需要该记录中的正确值才能继续执行。
    • 如果正确的值不能通过单个查询执行,比如更新或选择进入,你应该用一个异步作业和你所有的业务逻辑以编程方式更新旧表,这是丑陋而漫长的路,但在旧版应用中很常见。
    • 我现在看到 flyway 支持基于 java 的迁移。也许这是正确的方法。
    【解决方案2】:

    我遇到了类似的问题,我使用 flyway 脚本分 3 步解决了它。这适用于 Postgres。

    1. 添加没有唯一约束的新列

      alter table my_table add column my_new_column varchar(255);
      
    2. 用另一个表中的数据填充该表。

    下面的子查询可以根据需要更新以从另一个表中提取数据

       update my_table m set my_new_column=sq.value from (select value, foreign_id from another_table) as sq where sq.foreign_id=m.id;
    

    同样你可以使用当前表的现有列计算新列的新值:

       update my_table set my_new_column=concat(existing_column_1, existing_column_2);
    
    1. 添加唯一性约束:

      alter table my_table add constraint my_table_my_new_column_uk unique (my_new_column);
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      • 2012-09-05
      • 2015-11-27
      • 1970-01-01
      • 2017-06-07
      • 2015-02-09
      • 2012-02-25
      相关资源
      最近更新 更多