【DB筆試面試474】普通錶轉換為分區表有哪些辦法?
- 2019 年 10 月 11 日
- 筆記
題目部分
普通錶轉換為分區表有哪些辦法?
答案部分
將普通錶轉換成分區表有以下4種方法:
(1)導出/導入方法(Export/Import Method)
(2)子查詢插入方法(Insert With a Subquery Method)
(3)分區交換方法(Partition Exchange Method)
(4)在線重定義方法(DBMS_REDEFINITION Method)
下面介紹一下這幾種方法的主要過程:
1、導出/導入方法(Export/Import Method)
採用邏輯導出/導入很簡單,首先在源庫建立分區表,然後將數據導出,導入到新建的分區表即可。
(1)導出表:exp usr/pswd tables=T_TEST_LHR file=exp_lhr.dmp
(2)刪除表:DROP TABLE T_TEST_LHR
(3)重建分區表的定義:
CREATE TABLE T_TEST_LHR(QTY NUMBER(3), NAME VARCHAR2(15)) PARTITION BY RANGE (QTY) (PARTITION P1 VALUES LESS THAN (501), PARTITION P2 VALUES LESS THAN (MAXVALUE));
(4)利用ignore=y來導入分區表:imp usr/pswd file=exp_lhr.dmp ignore=y
2、子查詢插入方法(Insert With a Subquery Method)
主要過程如下所示,其中,T表是非分區表:
LHR@DLHR> CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME) 2 (PARTITION T1 VALUES LESS THAN (TO_DATE('201311', 'YYYYMM')), 3 PARTITION T2 VALUES LESS THAN (TO_DATE('201606', 'YYYYMM')), 4 PARTITION T3 VALUES LESS THAN (MAXVALUE)) 5 AS SELECT ID, TIME FROM T;
Table created.
然後改變表名:
LHR@DLHR> RENAME T_NEW TO T; Table renamed.
3、分區交換方法(Partition Exchange Method)
主要過程有如下幾個步驟:
創建分區表:
LHR@DLHR> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME) 2 (PARTITION T1 VALUES LESS THAN (TO_DATE('2013-11-1', 'YYYY-MM-DD')), 3 PARTITION T2 VALUES LESS THAN (MAXVALUE)); Table created.
交換數據:
LHR@DLHR> ALTER TABLE T_NEW EXCHANGE PARTITION T1 WITH TABLE T; Table altered.
改變表名:
LHR@DLHR> RENAME T TO T_OLD; Table renamed. LHR@DLHR> RENAME T_NEW TO T; Table renamed.
4、在線重定義方法(DBMS_REDEFINITION Method)
主要過程如下所示:
LHR@DLHR> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER,'T','T_NEW','ID ID,TIME TIME',DBMS_REDEFINITION.CONS_USE_PK); PL/SQL procedure successfully completed. LHR@DLHR> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(user, 'T', 'T_NEW'); PL/SQL procedure successfully completed.
關於這幾種方法的優缺點及適用情景如下表所示:
方法 |
主要過程 |
優點 |
缺點 |
適用情況 |
---|---|---|---|---|
導出/導入方法(Export/Import Method) |
採用邏輯導出/導入,首先在源庫建立分區表,然後將數據導出,導入到新建的分區表即可。 |
操作簡單。 |
整個實施過程中,目標表將不能進行DML操作。 |
該方法適用於業務量較小的表。 |
子查詢插入方法(Insert With a Subquery Method) |
採用CTAS的方式創建分區表,然後執行RENAME操作即可。 |
方法簡單易用,由於採用DDL語句,不會產生Undo日誌,且只會產生少量Redo日誌,效率相對較高,而且建表完成後數據已經分佈到各個分區中了。 |
對於數據的一致性方面需要做額外的考慮。在執行CREATE TABLE語句和RENAME T_NEW TO T(T_NEW為中間表)語句時,T表不能進行DML操作。如果要保證一致性,那麼需要在執行完語句後對數據進行檢查,而這個代價是比較大的。另外,在執行RENAME語句時,其它會話將不能訪問T表。 |
該方法適用於修改不頻繁的表,在閑時進行操作,表的數據量不宜太大。 |
分區交換方法(Partition Exchange Method) |
執行分區交換命令「ALTER TABLE T_NEW EXCHANGE PARTITION T1 WITH TABLE T;」交換普通表和分區表的某個特定分區。 |
只對數據字典中分區和表的定義進行了修改,沒有數據的修改或複製,效率最高。如果對數據在分區中的分佈沒有進一步要求的話,那麼實現比較簡單。在執行完RENAME操作後,可以檢查T_OLD(T_OLD為中間表)中是否存在數據,如果存在的話,那麼直接將這些數據插入到T中,可以保證對T插入的操作不會丟失。 |
存在一致性問題,在交換分區之後到RENAME T_NEW TO T(T_NEW為中間表)之前,查詢、更新和刪除會出現錯誤或訪問不到數據。如果要求數據分佈到多個分區中,那麼需要進行分區的SPLIT操作,會增加操作的複雜度,效率也會降低。 |
該方法適用於包含大數據量的錶轉到分區表中的一個分區的操作,應盡量在系統空閑時進行操作。 |
在線重定義方法(DBMS_REDEFINITION Method) |
使用DBMS_REDEFINITION包進行在線轉換。 |
保證數據的一致性,在大部分時間內,表T都可以正常執行DML操作,只在切換的瞬間鎖表,具有很高的可用性。這種方法具有很強的靈活性,對各種不同的需求都能滿足。而且,可以在切換前進行相應的授權並建立各種約束,可以做到切換完成後不再需要任何額外的管理操作。 |
在實現上比其它幾種方法略顯複雜。 |
該方法適用於7*24系統環境。 |
1、導出/導入方法(Export/Import Method)
採用邏輯導出/導入很簡單,首先在源庫建立分區表,然後將數據導出,導入到新建的分區表即可。
(1)導出表:exp usr/pswd tables=T_TEST_LHR file=exp_lhr.dmp
(2)刪除表:DROP TABLE T_TEST_LHR;
(3)重建分區表的定義:
CREATE TABLE T_TEST_LHR(QTY NUMBER(3), NAME VARCHAR2(15)) PARTITION BY RANGE (QTY) (PARTITION P1 VALUES LESS THAN (501), PARTITION P2 VALUES LESS THAN (MAXVALUE));
(4)利用ignore=y來導入分區表:imp usr/pswd file=exp_lhr.dmp ignore=y
2、子查詢插入方法(Insert With a Subquery Method)
優點:方法簡單易用,由於採用DDL語句,不會產生Undo日誌,且只會產生少量Redo日誌,效率相對較高,而且建表完成後數據已經分佈到各個分區中了。
不足:對於數據的一致性方面需要做額外的考慮。在執行CREATE TABLE語句和RENAME T_NEW TO T(T_NEW為中間表)語句時,T表不能進行DML操作。如果要保證一致性,那麼需要在執行完語句後對數據進行檢查,而這個代價是比較大的。另外,在執行RENAME語句時,其它會話將不能訪問T表。
該方法適用於修改不頻繁的表,在閑時進行操作,表的數據量不宜太大。
舉一個例子,創建普通表並插入測試數據。
LHR@DLHR> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE); Table created. LHR@DLHR> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS; 87069 rows created. LHR@DLHR> COMMIT; Commit complete. LHR@DLHR> SELECT TO_CHAR(T.TIME, 'YYYYMM'), COUNT(1) 2 FROM T 3 GROUP BY TO_CHAR(T.TIME, 'YYYYMM'); TO_CHA COUNT(1) ------ ---------- 201310 85984 201605 1085
創建一個分區表。需要注意的是,這裡的分區表的列後邊沒有數據類型。
LHR@DLHR> CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME) 2 (PARTITION T1 VALUES LESS THAN (TO_DATE('201311', 'YYYYMM')), 3 PARTITION T2 VALUES LESS THAN (TO_DATE('201606', 'YYYYMM')), 4 PARTITION T3 VALUES LESS THAN (MAXVALUE)) 5 AS SELECT ID, TIME FROM T; Table created.
改變表名:
LHR@DLHR> RENAME T_NEW TO T;
Table renamed.
驗證新表數據:
LHR@DLHR> SELECT TO_CHAR(T.TIME, 'YYYYMM'), COUNT(1) 2 FROM T 3 GROUP BY TO_CHAR(T.TIME, 'YYYYMM'); TO_CHA COUNT(1) ------ ---------- 201310 85984 201605 1085
3、分區交換方法(Partition Exchange Method)
本方法的優點是只對數據字典中分區和表的定義進行了修改,沒有數據的修改或複製,效率最高。如果對數據在分區中的分佈沒有進一步要求的話,那麼實現比較簡單。在執行完RENAME操作後,可以檢查T_OLD(T_OLD為中間表,參考下面的例子)中是否存在數據,如果存在的話,那麼直接將這些數據插入到T中,可以保證對T插入的操作不會丟失。
本方法的不足是存在一致性問題,在交換分區之後到RENAME T_NEW TO T(T_NEW為中間表)之前,查詢、更新和刪除會出現錯誤或訪問不到數據。如果要求數據分佈到多個分區中,那麼需要進行分區的SPLIT操作,會增加操作的複雜度,效率也會降低。
本方法適用於包含大數據量的錶轉到分區表中的一個分區的操作,應盡量在系統空閑時進行操作。舉個例子,創建普通表並插入測試數據的代碼如下所示:
LHR@DLHR> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE); Table created. LHR@DLHR> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS WHERE CREATED<=to_date('201311','YYYYMM'); 85984 rows created. LHR@DLHR> COMMIT; Commit complete. LHR@DLHR> SELECT TO_CHAR(T.TIME, 'YYYYMM'), COUNT(1) 2 FROM T 3 GROUP BY TO_CHAR(T.TIME, 'YYYYMM'); TO_CHA COUNT(1) ------ ---------- 201310 85984
創建分區表:
LHR@DLHR> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME) 2 (PARTITION T1 VALUES LESS THAN (TO_DATE('2013-11-1', 'YYYY-MM-DD')), 3 PARTITION T2 VALUES LESS THAN (MAXVALUE)); Table created.
交換數據:
LHR@DLHR> ALTER TABLE T_NEW EXCHANGE PARTITION T1 WITH TABLE T; Table altered.
改變表名:
LHR@DLHR> RENAME T TO T_OLD; Table renamed. LHR@DLHR> RENAME T_NEW TO T; Table renamed.
查詢數據:
LHR@DLHR> SELECT TO_CHAR(T.TIME, 'YYYYMM'), COUNT(1) 2 FROM T 3 GROUP BY TO_CHAR(T.TIME, 'YYYYMM'); TO_CHA COUNT(1) ------ ---------- 201310 85984
4、在線重定義方法(DBMS_REDEFINITION Method)
本方法的優點是保證數據的一致性,在大部分時間內,表T都可以正常執行DML操作,只在切換的瞬間鎖表,具有很高的可用性。這種方法具有很強的靈活性,對各種不同的需求都能滿足。而且,可以在切換前進行相應的授權並建立各種約束,可以做到切換完成後不再需要任何額外的管理操作。
本方法的不足之處是在實現上比上面幾種方法略顯複雜。
本方法適用於各種情況。舉個例子,創建普通表。
LHR@DLHR> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE); Table created. LHR@DLHR> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS; 87073 rows created.
然後執行:
LHR@DLHR> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T', DBMS_REDEFINITION.CONS_USE_PK); PL/SQL procedure successfully completed. LHR@DLHR> SELECT TO_CHAR(T.TIME, 'YYYYMM'), COUNT(1) 2 FROM T 3 GROUP BY TO_CHAR(T.TIME, 'YYYYMM'); TO_CHA COUNT(1) ------ ---------- 201310 85984 201605 1089
創建分區表:
LHR@DLHR> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME) 2 (PARTITION T1 VALUES LESS THAN (TO_DATE('201311', 'YYYYMM')), 3 PARTITION T2 VALUES LESS THAN (TO_DATE('201606', 'YYYYMM')), 4 PARTITION T3 VALUES LESS THAN (MAXVALUE)); Table created.
然後執行:
LHR@DLHR> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER,'T','T_NEW','ID ID,TIME TIME',DBMS_REDEFINITION.CONS_USE_PK); PL/SQL procedure successfully completed. LHR@DLHR> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(user, 'T', 'T_NEW'); PL/SQL procedure successfully completed.
& 說明:
有關普通錶轉換為分區表的具體操作過程可以參考我的BLOG:http://blog.itpub.net/26736162/viewspace-2109454/
本文選自《Oracle程序員面試筆試寶典》,作者:李華榮。
About Me:小麥苗
● 本文作者:小麥苗,只專註於數據庫的技術,更注重技術的運用
● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列題目來源於作者的學習筆記,部分整理自網絡,若有侵權或不當之處還請諒解
● 版權所有,歡迎分享本文,轉載請保留出處
● 題目解答若有不當之處,還望各位朋友批評指正,共同進步