Oracle大表添加字段


Oracle大表添加字段

在添加字段時,如果表數據量特別大。給添加的字段設置默認值,會消耗特別長的時間,而且所有行都要被鎖住。

在生產系統上,如果沒有安排足夠長的變更時間,可能會對業務帶來嚴重的影響。

對於這種情況,可以使用下面的語句:

alter table table_name add new_column data_type(precision) default 'value_string' not null;

也就是default + not null 這兩個關鍵詞組合的方式。

使用這種方法添加的字段,並不會真的修改每行的值,而是在sys.ecol$ 里添加一行數據,記錄下該字段的默認值。

雖然沒有進行物理存儲,但是對查詢、數據泵等操作都沒有影響 。

可以看下面示例:

SQL> col tabobj# for 999999999
SQL> col column for a20
SQL> col binarydefval for 99999999999999999999
SQL> select * from sys.ecol$;

未選定行

SQL> alter table test_object add create_user varchar2(30) default 'halberd' not null;

表已更改。

SQL> col tabobj# for 999999999
SQL> col column for a20
SQL> col defval for a15
SQL> select tabobj#,COLNUM, utl_raw.cast_to_varchar2(binarydefval) as defval from sys.ecol$;

   TABOBJ#     COLNUM DEFVAL
---------- ---------- ---------------
    247703         27 halberd

SQL> select object_id,object_name from dba_objects where object_name='TEST_OBJECT';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
    247703 TEST_OBJECT

SQL> select column_id from dba_tab_cols where owner='SYSTEM' and table_name='TEST_OBJECT' AND COLUMN_NAME='CREATE_USER';

 COLUMN_ID
----------
        27

這里我們驗證了,該方式添加字段后,在sys.ecol$ 里插入了一行數據 。

下面驗證,數據並沒有存儲到物理行中。


SQL> select max(column_id) from dba_tab_cols where table_name='TEST_OBJECT' AND OWNER='SYSTEM';

MAX(COLUMN_ID)
--------------
            27

SQL> update test_object set create_user='halberd' where rownum=1;

已更新 1 行。

SQL> commit;

提交完成。

SQL> select rowid,dbms_rowid.rowid_object(rowid) object_id,
dbms_rowid.rowid_relative_fno(rowid) rfno,
  2    3  dbms_rowid.rowid_block_number(rowid) rdbno,
  4  dbms_rowid.rowid_row_number(rowid) rno from test_object WHERE ROWNUM<=2;


ROWID               OBJECT_ID       RFNO      RDBNO        RNO
------------------ ---------- ---------- ---------- ----------
AAA8eXAABAADz9BAAA     247703          1     999233          0
AAA8eXAABAADz9BAAB     247703          1     999233          1


SQL> select file_id,relative_fno from cdb_data_files where relative_fno=1;

   FILE_ID RELATIVE_FNO
---------- ------------
       199            1

SQL> alter system dump datafile 199 block 999233;

system altered.

從上面的查詢結果來看,表test_object 有27個字段。我添加的新字段,就是第27個字段。如果是dump數據塊出來,顯示的就是row 26, 因為dump 結果是從row 0 開始的。

下面是dump的數據塊中前兩行的的內容:

block_row_dump:
tab 0, row 0, @0x3f5
tl: 114 fb: --H-FL-- lb: 0x3  cc: 27
col  0: [ 3]  53 59 53
col  1: [14]  49 5f 46 49 4c 45 23 5f 42 4c 4f 43 4b 23
col  2: *NULL*
col  3: [ 2]  c1 0a
col  4: [ 2]  c1 0a
col  5: [ 5]  49 4e 44 45 58
col  6: [ 7]  78 77 04 11 01 39 0f
col  7: [ 7]  78 77 04 11 01 39 0f
col  8: [19]  32 30 31 39 2d 30 34 2d 31 37 3a 30 30 3a 35 36 3a 31 34
col  9: [ 5]  56 41 4c 49 44
col 10: [ 1]  4e
col 11: [ 1]  4e
col 12: [ 1]  4e
col 13: [ 2]  c1 05
col 14: *NULL*
col 15: [ 4]  4e 4f 4e 45
col 16: *NULL*
col 17: [ 1]  59
col 18: [ 1]  4e
col 19: *NULL*
col 20: [ 1]  4e
col 21: [ 1]  4e
col 22: *NULL*
col 23: *NULL*
col 24: *NULL*
col 25: *NULL*
col 26: [ 7]  68 61 6c 62 65 72 64
tab 0, row 1, @0x1ec4
tl: 94 fb: --H-FL-- lb: 0x0  cc: 22
col  0: [ 3]  53 59 53
col  1: [ 6]  49 5f 4f 42 4a 33
col  2: *NULL*
col  3: [ 2]  c1 27
col  4: [ 2]  c1 27
col  5: [ 5]  49 4e 44 45 58
col  6: [ 7]  78 77 04 11 01 39 0f
col  7: [ 7]  78 77 04 11 01 39 0f
col  8: [19]  32 30 31 39 2d 30 34 2d 31 37 3a 30 30 3a 35 36 3a 31 34
col  9: [ 5]  56 41 4c 49 44
col 10: [ 1]  4e
col 11: [ 1]  4e
col 12: [ 1]  4e
col 13: [ 2]  c1 05
col 14: *NULL*
col 15: [ 4]  4e 4f 4e 45
col 16: *NULL*
col 17: [ 1]  59
col 18: [ 1]  4e
col 19: *NULL*
col 20: [ 1]  4e
col 21: [ 1]  4e
tab 0, row 2, @0x1e67

第一行, tab 0, row 0, @0x3f5 , 最后一個字段是第27個字段(dump 出來的字段數行數據都是從0 開始的)。


SQL> select utl_raw.cast_to_varchar2(replace('68 61 6c 62 65 72 64',' ')) as val from dual;

VAL
--------------------------------------------------------------------------------
halberd

而第二行, tab 0, row 1, @0x1ec4 ,則僅僅dump 出22個字段。說明22個字段之后的內容根本沒有存儲在數據塊中,所以dump的結果沒有這些字段的內容。

Author: halberd.lee

Created: 2020-09-16 Wed 10:38

Validate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM