一、
这个问题是比较复杂,特别是访问比较频繁的表。
可能需要分成几个小步骤来实现:
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上进行,开有没有额外的开销,如果没有,那么就可以做,如果有的话,那就要看情况而定了