在oracle 9i下線上重定義表
9i提供了聯機重定義表的方法,可以讓你在基本不影響原表的DML情況下修改表結構。
實際上,聯機重定義表並不是完全的聯機重定義,在最後交換表名的時候會短暫地鎖定原表和中間表,但這個過程很短暫,相對於傳統方法來說,這是一個進步。
/*
9i提供了聯機重定義表的方法,可以讓你在基本不影響原表的DML情況下修改表結構。
實際上,聯機重定義表並不是完全的聯機重定義,在最後交換表名的時候會短暫地鎖定原表和中間表,但這個過程很短暫,相對於傳統方法來說,這是一個進步。
利用聯機重定義功能可以線上實現如下功能:
修改表的儲存引數
移動該表到相同 Schema 下的 不同表空間內
新增並行查詢支援
新增或刪除分割槽
重建表以便減少碎片
在普通表和索引組織(index-organized)表之間互相轉換
新增或刪除列,重新定義列的資料型別
新增/刪除索引
做一個從普通表到分割槽表之間的轉換操作.
修改約束
需要的許可權:
CREATE ANY TABLE
ALTER ANY TABLE
DROP ANY TABLE
LOCK ANY TABLE
SELECT ANY TABLE
限制條件:
·你必須有足以維護兩份表格複製的空間。
·你不能更改主鍵欄。
·表格必須有主鍵。
·必須在同一個大綱中進行表格重定義。
·在重定義操作完成之前,你不能對新加欄加以NOT NULL約束。
·表格不能包含LONG、BFILE以及使用者型別(UDT)。
·不能重定義連結串列(clustered tables)。
·不能在SYS和SYSTEM大綱中重定義表格。
·不能用具體化檢視日誌(materialized view logs)來重定義表格;不能重定義含有具體化檢視的表格。
·不能在重定義過程中進行橫向分集(horizontal subsetting)。
基本步驟如下
第一步:利用dbms_redefinition.can_redef_table過程檢查該表是否能被線上重定義。
如果這一步不丟擲異常,說明該表是可以線上重定義的。
第二步:建立一個與原表類似的空表結構,用於重定義該表,這裡叫做是中間表
在這裡你可以定義表的新列名、新資料型別、列順序、儲存引數等。注意,為了提高效率,在這一步不要建立索引和約束。
第三步:用dbms_redefinition.start_redef_table procedure定義重構開始
這個過程將會自動執行如下操作:
1、插入所有行從原有表到中間表
2、建立MLOG$_xxx快照與快照日誌,臨時儲存DML語句直到完成。
該過程可以輸入如下引數資訊
. 使用者的名稱
. 原表的名稱
. 中間表的名稱
. 原表和中間表的列的對映關係。
這個引數預設值是null,表示原表和中間表的欄位按原表的順序一一對應。但如果需要在中間表新增、刪除欄位,修改欄位資料型別、改變欄位順序,則必須要把這個引數填寫好。不同欄位間用都好分隔。
作對映時,對應的欄位先寫原表欄位,然後再寫中間表的欄位。
如新增欄位,並改變列的資料型別:
原表 a(id int ,name varchar2(10))
中間表b(id number,new_name varchar2(10),sex int)
exec dbms_redefinition.start_redef_table procedure('suk','a','b','name new_name,id id')
或者exec dbms_redefinition.start_redef_table procedure('suk','a','b','id id,name new_name')
再如 同時新增、刪除欄位:
原表 a(id int ,name varchar2(10))
中間表b(id number,sex int)
exec dbms_redefinition.start_redef_table procedure('suk','a','b','id id')
對映時可以使用一些簡單函式,如
exec dbms_redefinition.start_redef_table procedure('suk','a','b','to_char(id) id')
所以,如果資料量很大的話,這一步會比較慢。
第四步:呼叫DBMS_REDEFINITION.SYNC_INTERIM_TABLE過程同步原表與中間表的資料
這一步不是必須的,如果省略這一步,在finish_redef_table也會執行這一步驟。但我們應該把這一步放在為中間表建立索引、約束等前面,這樣可以提高效率。
第五步:與原表一致,在中間表上面建立約束,索引,觸發器
與原表一致(如果需要),中間表的物件許可權被授予給別的物件
注意:在中間表建立外來鍵約束時應該加上DISABLE關鍵字
第六步:用dbms_redefinition.finish_redef_table過程完成表的最終重定義
該過程將自動完成
. 應用快照日誌中的DML到中間表
. 互換原表與中間表的名字,包括所有可能出現的資料字典
. 但是需要注意的是,並不對換約束,索引,觸發器的名稱,這些需要手工修改
. 刪除MLOG$_XXX
. 啟用原來在中間表上的外來鍵
同時,執行這一步時,oracle會短暫地LOCK原表和中間表
第七步:刪除中間表、
第八步:如果是920以上,可以利用ALTER TABLE ... RENAME CONSTRAINT ...語句來修改約束名稱,如果以下版本,就只有刪除並重建了,當然,如果約束名稱並不重要,也就無所謂了
第九步:如果重組織失敗,那麼你就必須採取特殊的步驟來讓它重新開始。由於重定義過程需要建立表格的快照,因此為了重新開始這一過程,你必須呼叫DBMS_REDEFINITION.ABORT_REDEF_TABLE來釋放快照。
幾個需要注意的地方:
. 在重定義表期間,不允許對中間表作任何DML操作
*/
--以下是一個利用9i的聯機重定義表刪除欄位的簡單過程
--原表結構
SQL> desc channel
Name Type Nullable Default Comments
------------------- -------------- -------- ------- --------
CHANNEL_ID NUMBER(16)
CHANNEL_NAME VARCHAR2(120)
PARENT_CHANNEL_ID NUMBER(16) Y
CHANNEL_URL VARCHAR2(256) Y
CHANNEL_DESCRIPTION VARCHAR2(4000) Y
STYLE_CLASS VARCHAR2(120) Y
CONFIGURE_FILE VARCHAR2(120) Y
CHANNEL_SEQUENCE NUMBER(4) Y 9999
CHANNEL_LEVEL NUMBER(2) Y
CREATE_DATE DATE SYSDATE
SELF_TAG_ID NUMBER(8) Y
CHANNEL_CODE VARCHAR2(120) Y
--建立中間表
SQL> create table channel_test as select * from channel where 1=2;
Table created
SQL> alter table channel_test drop column STYLE_CLASS;
Table altered
SQL> desc channel_test
Name Type Nullable Default Comments
------------------- -------------- -------- ------- --------
CHANNEL_ID NUMBER(16)
CHANNEL_NAME VARCHAR2(120)
PARENT_CHANNEL_ID NUMBER(16) Y
CHANNEL_URL VARCHAR2(256) Y
CHANNEL_DESCRIPTION VARCHAR2(4000) Y
CONFIGURE_FILE VARCHAR2(120) Y
CHANNEL_SEQUENCE NUMBER(4) Y
CHANNEL_LEVEL NUMBER(2) Y
CREATE_DATE DATE
SELF_TAG_ID NUMBER(8) Y
CHANNEL_CODE VARCHAR2(120) Y
--檢測是否能線上重定義表
SQL> exec dbms_redefinition.can_redef_table('suk','channel');
PL/SQL procedure successfully completed
--開始重定義表
SQL> exec dbms_redefinition.start_redef_table('suk','channel','channel_test','channel_id,CHANNEL_NAME,PARENT_CHANNEL_ID,CHANNEL_URL,CHANNEL_DESCRIPTION,CONFIGURE_FILE,CHANNEL_SEQUENCE,CHANNEL_LEVEL,CREATE_DATE,SELF_TAG_ID,CHANNEL_CODE');
PL/SQL procedure successfully completed
--完成重定義表
SQL> exec dbms_redefinition.finish_redef_table('suk','channel','channel_test');
PL/SQL procedure successfully completed
--檢視重定義後的表結構,可以看到表channel的結構已經改變
SQL> desc channel
Name Type Nullable Default Comments
------------------- -------------- -------- ------- --------
CHANNEL_ID NUMBER(16)
CHANNEL_NAME VARCHAR2(120)
PARENT_CHANNEL_ID NUMBER(16) Y
CHANNEL_URL VARCHAR2(256) Y
CHANNEL_DESCRIPTION VARCHAR2(4000) Y
CONFIGURE_FILE VARCHAR2(120) Y
CHANNEL_SEQUENCE NUMBER(4) Y
CHANNEL_LEVEL NUMBER(2) Y
CREATE_DATE DATE
SELF_TAG_ID NUMBER(8) Y
CHANNEL_CODE VARCHAR2(120) Y
參考文件:
piner 9i新特性之——線上表格重定義研究
tahiti.oracle.com
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63741/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 表線上重定義Oracle
- oracle表線上重定義Oracle
- 【Oracle】線上重定義表Oracle
- Oracle 9i中表的線上重定義(轉)Oracle
- Oracle表的線上重定義(一)Oracle
- oracle線上重定義表步驟Oracle
- Oracle中重建表的線上重定義Oracle
- 線上重定義表ORACLE 11GOracle
- oracle 線上重定義Oracle
- Oracle線上重定義Oracle
- 【TABLE】oracle表線上重定義注意事項Oracle
- oracle實驗記錄 (線上重定義表)Oracle
- ORACLE 線上重新定義表分割槽表重定義為普通表。Oracle
- Oracle Online Redefinition線上重定義(下)Oracle
- 9i新特性之——線上表格重定義研究在(轉)
- oracle 9i線上重定義功能應用於生產庫Oracle
- Oracle的線上重定義(轉)Oracle
- dbms_redefinition線上重定義表
- 使用ORACLE線上重定義將普通表改為分割槽表Oracle
- oracle分割槽表線上重定義欄位not null問題OracleNull
- ORACLE 普通錶轉換成分割槽表(線上重定義)Oracle
- 資料庫表的線上重定義資料庫
- 利用DBMS_REDEFINITION線上重定義表
- 【Oracle】利用線上重定義的方式改變普通表為分割槽表Oracle
- ORACLE 普通錶轉換成分割槽表(線上重定義)(zt)Oracle
- Oracle線上重定義之DBMS_REDEFINITIONOracle
- Oracle Online Redefinition線上重定義(上)Oracle
- Oracle Online Redefinition線上重定義(中)Oracle
- 普通錶轉換分割槽表-線上重定義
- 分割槽表和dbms_redefinition包線上重定義表
- 使用DBMS_REDEFINITION線上重定義表普通表為分割槽表
- 線上重定義 ?普通錶轉換成分割槽表
- OCM實驗-使用線上重定義方式遷移表
- 海量資料處理_表分割槽(線上重定義)
- oracle 線上重組表Oracle
- 使用線上重定義方法改造普通表為分割槽表實戰
- 線上重定義表(Redefine Tables Online) - dbms_redefinition
- Online Redefinition線上重定義(三)--多表關聯重定義案例