大表上新增字段问题--相关解决方案

一、

这个问题是比较复杂,特别是访问比较频繁的表。
可能需要分成几个小步骤来实现:
1、先增加字段,不要设置默认值。
2、然后给该字段赋值,update方式
3、最后修改表结构,设置默认值。

 

二、

1、检查此表是否有被其它对象引用,如果引用对象过多且并发操作多,则此操作一定要避免在业务高峰期操作,如果引用量特别多且相应对象并发操作多,则可能要考虑短暂停止此表及相关引用对象相关模块的服务(如果可以分离的话),如果不能够,则要考虑整个业务暂时停止。
2、正式操作的时候采用以下顺序可以降低操作对系统的影响:
   1)添加字段,不加默认值
   2)添加默认值
   ---1,2步要分开来做的原因是如果直接加含有默认值的字段则原来的记录上都会更新成默认值,这样系统很大机会出现不可用甚至崩溃(redo,undo,数据库连接,相关对象失效导致访问的进程相互编译导致等待等。。。),而分开操作,则原来记录上为null值,默认值只会在新加记录上生效,对系统影响很小
   3)如果有引用对象失效,立即编译失效对象,避免影响业务
   4)采用批量更新的方式对新加字段的值更新为默认值,根据业务对此表的DML频繁度来控制批量,如果频繁度高,则批量降低,避免锁定造成堵塞,另外更新的时候还要再次确认是null值才设置成默认值。 
      一个比较合适的方式大致如下(如果系统很繁忙,为了安全还可以考虑批量操作过程中再增加休息(用dbms_lock.sleep),保证系统影响度低,安全可靠):
      cursor vCur_update is select rowid from 表名 where 新加字段 is null;
        begin
             open vCur_update;
             fetch  vCur_update bulk collect
                     into vRowid_table limit  1000;
            forall i in 1 .. vRowid_table .count
              update 表名 set 新加字段=默认值 where rowid=vRowid_table(i) and 新加字段 is null;--避免新加字段在其它业务操作中已变成非null值且不是默认值
              commit;
             exit when vCur_update%notfound;
            end loop;
           close vCur_update;
        end;
     
   --批量更新null值至默认值的操作要在设置完默认值后才做,原因是如果在添加字段后立即更新,则在更新过程中新进记录新加字段还是为null值,这样需要在添加默认值后再更新一次才能够保证符合真正的业务需求,否则仍然有可能存在null值

 

三、

你可以先建一个相同的表结构,加一个自增的字段啊,然后把这个大表的数据导入啊。然后删除大表,把这个表名修改成原来的那个表不就行了

 

四、

先把表里的数据转移,select * into XX
清空表
再增加字段
回填数据

 

五、

1.用脚本去增加
alter table tabname add id int identity

alter table Tablename add columnname int default(0) not null
2.通过转换到临时表创建自增列

 

六、

如果添加新字段的话,有可能会引起额外的开销。建议这样,先做一个和该表A结构完全相同的表B,然后在表B上进行,开有没有额外的开销,如果没有,那么就可以做,如果有的话,那就要看情况而定了

 

 

### Hive 新增字段失败的原因分析与解决方案 #### 原因分析 当尝试通过 `ALTER TABLE ... ADD COLUMNS` 向 Hive 新增字段时,可能会遇到错误。这种问题通常由以下几个因素引起: 1. **分区的数据文件不兼容** 如果目标是一个分区,在新增字段后,旧分区中的数据可能不会自动更新以包含新字段的信息。这可能导致查询时出现异常或缺失值的情况[^4]。 2. **元数据同步问题** 当向内部分区新增字段时,如果未正确处理元数据的变更,则可能出现元数据与实际存储数据之间的不一致。特别是对于已存在的分区,其对应的 HDFS 文件路径可能并未反映最新的模式定义[^5]。 3. **字段位置冲突** 新增字段的位置如果不明确,默认会被追加到现有字段之后。然而,某些场景下可能存在依赖于特定字段顺序的操作逻辑,从而引发潜在问题[^3]。 4. **外部 vs 内部差异** 对于内部而言,删除的同时也会清除底层数据;而对于外部来说,仅移除的是元数据信息而非真实数据本身。因此针对不同类型格采取不同策略至关重要[^5]。 --- #### 解决方案 以下是几种常见情况下可以采用的具体措施来应对上述提到的各种挑战: ##### 方法一:重建并迁移数据 这种方法适用于复杂情况下的彻底修正需求。 - 将原始内部转换成外部(防止丢失数据),或者直接基于外置操作; - 创建一张具有期望结构的新- 使用 SQL 语句把原有数据导入至新建好的里头去; - 完毕后再做必要的权限设置以及验证工作确保一切正常运作起来即可完成整个流程。 ```sql -- 步骤示例: ALTER TABLE original_internal_table SET TBLPROPERTIES('EXTERNAL'='TRUE'); CREATE EXTERNAL TABLE IF NOT EXISTS new_external_table ( col1 STRING, col2 INT, ... added_column STRING COMMENT 'This is the newly added column' ) PARTITIONED BY (partition_col STRING); INSERT INTO new_external_table SELECT *, NULL FROM original_internal_table; MSCK REPAIR TABLE new_external_table; ``` ##### 方法二:手动调整分区内容 如果只是单纯因为历史分区缺少最新字段而导致读取报错的话,可以通过如下手段单独解决问题而不必完全重构整张: - 首先确认哪些具体分区内存在问题- 接着利用 DDL/DML 结合的方式重新加载这些受影响区域内的资料使之符合当前架构标准[^4]。 ```sql -- 示例代码片段展示如何处理单一分区上的字段缺失状况 ALTER TABLE your_table DROP IF EXISTS PARTITION(partition_key=value); INSERT OVERWRITE TABLE your_table PARTITION(partition_key=value) SELECT existing_columns, default_value_for_new_field FROM source_data WHERE partition_key=value; ``` ##### 方法三:使用 CASCADE 参数(若有支持) 尽管官方文档指出并非所有版本都全面支持此特性,但在适用条件下启用级联修改选项能够简化过程减少额外手工干预步骤数量[^1]^。 ```sql ALTER TABLE your_table ADD COLUMNS(new_column STRING) CASCADE; ``` 注意检查所使用的 Hive 版本是否具备此项能力之前需查阅对应发行说明材料获取确切消息。 --- ### 总结 综上所述,面对 Hive 中 “ALTER TABLE ADD COLUMNS” 失败的情形可以从多个角度出发寻找合适的处置办法。无论是选择较为激进的整体替换途径还是局部精细化调控均各有优劣之处需要依据实际情况灵活运用才能达到最佳效果。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值