在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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 線上重定義與普通表改為分割槽表
- 線上重定義方式將普通表修改為分割槽表
- 壓縮錶轉非壓縮表(線上重定義)
- 指令碼:線上重定義,從普通表到分割槽表,redefinition_table.sh指令碼
- Oracle EBR 基於版本重定義Oracle
- 聯機重定義表在10g的改進
- 線上重定義的操作步驟__普通錶轉換為分割槽表的實驗案例
- oracle 9i臨時表產生過多redoOracle
- ORACLE線上切換undo表空間Oracle
- oracle 線上重新定義,普通表改變分割槽表,分割槽表可以更改型別、分割槽欄位等Oracle型別
- oracle 9i資料庫做spaOracle資料庫
- qt之函式重定義QT函式
- 10月21日線上研討會 | 軟體定義汽車下的產品線複用管理
- Installing Oracle 9i on OELRHEL 4.8 64bitOracle
- Oracle 19c 線上縮減 UNDO 表空間 容量Oracle
- 網路口碑營銷的重點是線上還是線下?
- 會員系統融合線上線下的意義是什麼?
- LightDB 22.4 新特性之相容Oracle線上轉換普通表為分割槽表Oracle
- 重學java之類的定義Java
- oracle 線上調整redoOracle
- 在electron下實現PDF線上預覽功能
- c++繼承,隱藏(重定義)C++繼承
- C++中過載、重寫、重定義的區別C++
- 在jQuery定義自己函式jQuery函式
- 在 SAP ABAP Gateway 系統上定義後臺系統的 AliasGateway
- 想問一下你的那個模板檔案定義在根目錄下Template是通過什麼方式定義的?
- Oracle 9i統計資訊備份與恢復Oracle
- SAP Spartacus 如何重定義登入 Login Component
- 自定義RadiusBackgroundSpan在textview設定tagTextView
- 榮耀9i隱藏劉海設定方法 榮耀9i怎麼隱藏劉海?
- oracle 線上rename資料檔案Oracle
- Oracle中刪除表中的重複資料Oracle
- 在Oracle Linux 7.1上安裝DockerOracleLinuxDocker
- 雲端IDE如何重定義開發體驗IDE
- DMAIC定義階段的重點是什麼?AI
- 【配置上線】Oracle資料庫Linux系統下安裝(圖形介面)Oracle資料庫Linux
- ORACLE expdp在表空間較多的情況下執行非常緩慢Oracle
- Oracle 12C新特性-線上把非分割槽錶轉為分割槽表Oracle