程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> ORACLE 遷移到 DB2:如何把 Oracle partition 轉化到 DB2

ORACLE 遷移到 DB2:如何把 Oracle partition 轉化到 DB2

編輯:DB2教程

數據庫 Partitioning 概述

當數據庫表中的數據不斷增大,必然會導致數據的查詢速度降低,從而應用程序的性能就會下降,這時就應該考慮對表進行分區,數據放在不同的分區這樣在進行數據讀取時就可以並行處理,從很大程度上提高數據的訪問速度。還需要說明的是,表進行分區後,邏輯上表還是完整的,而只是把表中的數據在物理上存放到不同的表空間中(物理文件上),從而進行數據查詢時,就不至於每次都掃描整張表。

總體來說,partition 可以從很大程度上改善數據庫的性能,並且對數據的分區管理還可以改善管理員管理數據的靈活性以及可用性,如某個分區出現故障,其它分區的數據仍可用,同時管理員只需修復該分區即可。同時可以把不同的分區映射到磁盤從而均衡 IO。

Oracle 與 DB2 的 partitioning

圖 1. 不同共享模式架構
不同共享模式架構

無論是 oracle 還是 db2,為了提高數據的讀寫性能,在系統架構方面都采取了並行的方式,對於並行模式又可以分為以下幾種:

  • Share everything

    這是最簡單的一種方式,即在同一台機器上多個進程並行執行,處理器在處理過程中共享內存緩沖池、共享物理存儲。這種方式受制於機器的物理資源。

  • Share disk

    在這種架構下,所有的機器共享一個物理存儲;由於每台物理機器都獨立於數據庫中數據,這就能夠最大限度的保證了機器數量的自由行。同樣,由於每台機器都會掃描磁盤上的所有表,也就導致總體性能受制於大型系統。

  • Share memory

    即所有機器共享內存。

  • Share nothing

    數據分布在所有的機器上,每台機器有各自的存儲。正因為如此,當增減機器的時候也會給整個系統帶來影響;同時,因為每台機器只能訪問各自的物理存儲,這也就保證了系統性能可以近乎線性的提高。

Oracle 分區介紹

Oracle 采用的是 share-disk 架構,因此 oracle 的分區特性只是在同一磁盤上,這就決定了它不存在 DPF 的特性,只存在表分區。下面主要介紹一下 oracle 的幾種主要的表分區。

  • Range partition(區間分區)

    Range partition 是比較常見的一種分區方式,它把數據基於分區鍵劃定的范圍映射到分區內。分區鍵即表中的某一列,而日期是經常被采用的分區鍵。Range partition 具有如下性質:

    • 通過 values less than 子句指定上限值,大於或等於該值得數據都被分配到下一個分區。當然分區的下限值即為上一個分區的上限值。
    • 在最高分區中定義 MAXVALUE。它代表了高於其它所有分區的值,包括控制。
  • list partition(列表分區)

    List partition 能夠明確指定用列中的哪些具體的值來進行分區,這樣的分區方式是 Range 和 Hash 所做不到的,這種方式的有點就是:用戶可以組織和分組哪些沒有順序和沒有關系的數據集合,用戶可以明確的控制多少行被分區。

  • hash partition(散列分區)

    Hash Partitioning 映射數據到基於 HASH 算法的分區上,HASH 算法將應用你指定的分區關鍵字,平均的分那些在 Partitions 中的行。給每 一個分區近似相同的大小,要保證數據能平均分配,分區數一般是 2N。比如說,需要 insert sales_hash 一條數據,ORACLE 會通過 HASH 算法處理 salesman_id,然後找到對於的分區表進行 insert。Hash Partitioning 是為跨越設備的分布式數據提供了一種理想的方法,HASH 算法也很容易轉化成 RANGE 分區方法,特別是當被分區的數據不是歷史數據時。

  • 復合分區

    傳統的復合分區包括范圍 - 列表分區和范圍 - 散列分區,范圍 - 列表分區是范圍和列表技術的組合,其實質是首先對表數據按照范圍進行分區,然後再利用列表對每個范圍再次分區。每個子分區的內容表示數據的邏輯子集。范圍 - 散列分區是范圍和散列技術的組合,其實質就是首先對表進行區間分區,然後再把數據散列的分別在幾個表空間中。

Oralce11G 中又增加了 RANGE-RANGE、LIST-RANG、LIST-HASH 和 LIST-LIST,但是在本文中沒有考慮這 4 中復合分區。

DB2 分區介紹

在 DB2 中,分區可以從以下幾個方面來說:

  • 數據庫分區

    即數據庫分區特性(DPF),如圖 2 所示。

  • 表分區

    在 db2 的表分區又可以稱為數據分區或者區間分區。這種數據組織模式與 oracle 類似,就是把數據分散存儲於不同的存儲對象中,這種存儲對象是按照 1 個或多個表列得值來進行劃分的數據分區或者數據范圍。每個數據分區被存儲在不同的表空間中。

  • MDC

    多維數據集即 MDC 是在 DB2 V8 時引入的,它把類似的數據按照多維聚集在一塊存放在磁盤上,這樣數據在讀取是就可以整塊的讀取從而提高了 I/O 的效率。例如對於 Product=car,Region=East 的所有行,可以按照這兩個字段作為維,把這兩個字段相同的數據存儲在相同的位置,即所謂的塊(block),一個塊的大小等於表空間的擴展數據塊(extent)大小,擴展數據塊是磁盤上的一組連續頁,所以將這些具有類似值的行在物理上是存放在連續的數據頁上。了解 MDC 相關內容和細節,可以查看 DB2 9.7 信息中心的“多維集群表”。

圖 2.DB2 DPF 架構
DB2 DPF 架構

Oracle 分區與 DB2 分區的對比

  • Oracle 的區間分區

    Oracle 的區間分區(Range partition)與 DB2 的表分區(table partition)在概念上極為匹配,只是在表分區的定義上有所區別。因此 Oracle 中的區間分區與 DB2 的表分區對映,在做數據的遷移的時候可以直接把 Oracle 中的區間分區遷移到 DB2 的表分區。Oracle 中區間分區示例如清單 1 所示:

    清單 1. Oracle 中的區間分區示例
     CREATE TABLE sales 
     ( 
     year int, 
     month int 
     ) 
     PARTITION BY RANGE (year, month) 
     (PARTITION p1 VALUES LESS THAN (2002,4) tablespace tbsp1, 
     PARTITION p2 VALUES LESS THAN (2002,7) tablespace tbsp2, 
     PARTITION p3 VALUES LESS THAN (2002,10) tablespace tbsp3, 
     PARTITION p4 VALUES LESS THAN (2002,13) tablespace tbsp4, 
     PARTITION p5 VALUES LESS THAN (2003,4) tablespace tbsp5, 
     PARTITION p6 VALUES LESS THAN (2003,7) tablespace tbsp6, 
     PARTITION p7 VALUES LESS THAN (2003,10) tablespace tbsp7, 
     PARTITION p8 VALUES LESS THAN (MAXVALUE, MAXVALUE) tablespace tbsp8 );

    其對應的 db2 中的表分區定義:

    清單 2. DB2 中的表分區示例
     CREATE TABLE sales 
     ( 
     year INT, 
     month INT 
     ) 
     PARTITION BY RANGE (year, month) 
     (STARTING FROM (2001, 1) 
     ENDING (2001,3) IN tbsp1, 
     ENDING (2001,6) IN tbsp2, 
     ENDING (2001,9) IN tbsp3, 
     ENDING (2001,12) IN tbsp4, 
     ENDING (2002,3) IN tbsp5, 
     ENDING (2002,6) IN tbsp6, 
     ENDING (2002,9) IN tbsp7, 
     ENDING AT MAXVALUE );
  • Oracle 的列表分區

    Oracle 中的列表分區(list partition)可以直接映射到 DB2 中的帶生成列的表分區中,在前面已經講過 Oracle 的列表分區的定義,DB2 的表分區的定義中提供了一個可以帶生成列的方法,這樣帶生成列的表分區與 Oracle 的列表分區邏輯結構類似。

    清單 3. Oracle 中的列表分區示例
     CREATE TABLE customer 
     ( 
     cust_id int, 
     cust_prov varchar2(2) 
     Chapter 2. Language compatibility features 127 
     ) 
     PARTITION BY LIST (cust_prov) 
     (PARTITION p1 VALUES ('AB', 'MB') tablespace tbsp_ab, 
     PARTITION p2 VALUES ('BC') tablespace tbsp_bc, 
     PARTITION p3 VALUES ('SA') tablespace tbsp_mb, 
    … . 
     PARTITION p13 VALUES ('YT') tablespace tbsp_yt, 
     PARTITION p14 VALUES(DEFAULT) tablespace tbsp_remainder );

    該表對應的 DB2 的帶生成列的表分區的示例如下:

    清單 4. DB2 中帶生成列的表分區示例
    				 CREATE TABLE customer 
     ( 
     cust_id INT, 
     cust_prov CHAR(2), 
     cust_prov_gen GENERATED ALWAYS AS 
     (CASE 
     WHEN cust_prov = 'AB' THEN 1 
     WHEN cust_prov = 'BC' THEN 2 
     WHEN cust_prov = 'MB' THEN 1 
     WHEN cust_prov = 'SA' THEN 3 
     ... 
     WHEN cust_prov = 'YT' THEN 13 
     ELSE 14 
     END) 
     ) 
     IN tbsp_ab, tbsp_bc, tbsp_mb, .... tbsp_remainder 
     PARTITION BY RANGE (cust_prov_gen) 
     (STARTING 1 ENDING 14 EVERY 1);

    另外需要說的是把 oracle 的 List partition 映射到 db2 的 MDC 也可以是一種選擇。

  • Oracle 的哈希分區

    Oracle 中的哈希分區(hash partition)的定義在第一節中已經說明,那麼在 DB2 中用到哈希算法的只有 DPF 的定義中,雖然在物理上 Oracle 沒有 DPF 的概念,但是數據在邏輯上都能按照哈希算法分配到對應的分區上。因此在數據遷移是可以把 Oracle 的哈希分區映射到 DB2 中按照哈希算法分布的 DPF 上。而且在實際應用中,這比 Oracle 的哈希分區執行效率更好

    如 Oracle 中哈希分區示例

    清單 5. Oracle 中的哈希分區示例
     CREATE TABLE hash_table 
     ( 
     hash_part date, 
     hash_data varchar2(20) 
     ) 
     PARTITION BY HASH(hash_part) 
     (partition p1 tablespace tbsp1, 
     partition p2 tablespace tbsp2 
     );

    映射到 DB2 的 DPF 示例如下:

    清單 6. DB2 中帶生成列的表分區示例
     CREATE TABLE partition_table 
     (partition_date date NOT NULL, 
     partition_data VARCHAR(20) NOT NULL 
     ) 
     IN tbsp_parts 
     DISTRIBUTE BY HASH (partition_date);

    綜上所述,Oracle 中的任一單一分區均可以在 DB2 中實現,反觀之,DB2 特有的多維集群卻不能在 Oracle 中實現,

圖 3.Oracle 到 DB2 的分區映射
Oracle 到 DB2 的分區映射

在 DB2 中模擬 Oracle 復合分區

前面已經對 oracle 的復合分區進行了見到的介紹,這裡我們只對其中的兩種進行詳細的說明 (Range-list 和 Range-hash),並且介紹在 DB2 中如何與這兩種復合分區進行映射。

  • Range-list

    Range-list:該復合分區就是 Range partition 和 list partition 相結合的分區方法,前面已經介紹了 oracle 的 Range 分區和 List 分區在 DB2 中的實現方法,那麼這種復合分區對應到 DB2 中,我們只需綜合使用上述非復合分區的方法。

    例如在 ORACLE 數據庫有一張表 store,該表以字段 sales_date 作 range partition 以字段 store_distrct 作為 list partition,該表的定義如下 :

    清單 7. Oracle 中 Range-list 表示例
     create table store( 
    	 store_id varchar2(10), 
    	 store_district varchar2(20), 
    	 sales_date date, 
    	 revenue number(10) 
     ) 
    	 partition by range(sales_date) 
    	 subpartition by list(store_distrct) 
    		 subpartition template( 
    			 subpartition subpar1 values ('haidian') tablespace tbsp1, 
    			 subpartition subpar2 values ('chaoyang') tablespace tbsp1, 
    			 subpartition subpar3 values ('dongcheng') tablespace tbsp1, 
    			 subpartition subpar4 values ('xicheng') tablespace tbsp1, 
    			 subpartition subpar5 values ('fengtai') tablespace tbsp1, 
    			 subpartition subpar1 values ('shijingshan') tablespace tbsp1) 
    	 ( 
    	 partition par1 vales less than (to_date('01/04/2012','DD/MM/YYYY')), 
    	 partition par2 vales less than (to_date('01/07/2012','DD/MM/YYYY')), 
    	 partition par3 vales less than (to_date('01/10/2012','DD/MM/YYYY')), 
    	 partition par4 vales less than (MAXVALUE) 
    	 );

    我們如何將該 oracle 的 range-list 的表映射到 db2 中呢?前面我們以說明可以把 Range partition 映射到 db2 的 table partition,list partition 可以映射到帶生成列的 table partition。然而 db2 中沒有復合分區的概念,因此我們可以考慮映射到 db2 中以 table partition 加 MDC 來與之映射。那麼在 db2 中與之相對應的表定義如下:

    清單 8. Db2 中 table-MDC 表示例
     create table store( 
    	 store_id varchar(10), 
    	 store_distric varchar(20), 
    	 sales_date date, 
    	 revenue number(10) 
     ) 
     in tbsp1, tbsp2, tbsp3, tbsp4 
     partition by range(sales_date) 
    	 (starting from ('01/01/2012') ending ('31/12/2012') every (3 month)) 
     organize by dimension(store_district);

    和 oracle 一樣以 sales_date 字段作為 range 分區字段,以 store_district 字段做 MDC。

  • Range-hash

    該分區方法就是 Range partition 和 hash partition 相結合的分區方法,就是先安一個字段進行 range partition 然後再按照 hash partition 進行子分區。考慮到 DB2 在分區數據庫(DPF)中使用的 hash 方法,那麼要在 DB2 中模擬這種復合分區,我們用到了 DPF 及表分區:我們建立了一個分區組,這個分區組包含多個數據庫分區,然後在這個分區組下創建一個表空間,再在這個表空間下創建一張表,這樣,我們就能夠保證這個表中的數據將被分布到所有包含在內的分區上;同時我們用到了 DB2 的 Range 表分區,這樣,在任何一個數據庫分區內,數據也能夠按照范圍分區。

    清單 9. Oracle 中 Range-hash 表示例
     Create table car( 
     Car_id varchar2(10), 
     Sales_date date, 
     Sales_const number(10) 
     ) 
     Partition by range(sales_date) 
     Subpartition by hash(car_id) 
     (partition s1 values less than (to_date( ‘ 01/04/2012 ’ , ’ DD/MM/YYYY ’ )), 
     partition s2 values less than (to_date( ‘ 01/07/2012 ’ , ’ DD/MM/YYYY ’ )), 
     partition s3 values less than (to_date( ‘ 01/10/2012 ’ , ’ DD/MM/YYYY ’ )), 
     partition s4 values less than (MAXVALUE))

    DB2 中我們需要首先建立 DPF,然後再在此 DPF 上建立表分區,這裡就不詳細說明 DPF 的建立過程,DB2 中與上面表對應的表定義如下:

    清單 10. DB2 中 Range-DPF 表示例
     create table car( 
     car_id varchar(10), 
     sales_date date, 
     sales_cost number) 
     in tbsp1, tbsp2, tbsp3, tbsp4, tbsp5 
     distribute by hash(car_id) 
     partition by range(sales_date) 
     (starting from ('01/01/2012') ending ('31/12/2012') every (3 month));

Oracle Partition table 到 db2 的數據遷移

數據庫的遷移工作相當繁復,本文主要介紹 oracle 中的 partition table 如何遷移到 db2 中,其中相應的 oracle 到 db2 的 partition 的映射已經在前一節中進行了說明,下面就以 oracle 中的 range partitionhe 和 hash partition 的 table 遷移到 db2 為例,介紹如何將一個 oracle 的分區表遷移到 db2 中 , 對於 oracle 數據遷移到 db2 的主要流程這裡就不在贅述。除了對表完成映射外,還要完成表對象的部署、數據抽取、以及如何把數據部署到 db2 對應的分區表中。對於表 partition 表對象的部署我們還可以勉強手動創建來解決,然而對於數據的抽取和部署,卻很難完成,因此我們可以借助 IBM 開發的一些輔助工具,如 Migration Toolkit(MTK)、Data Movement Tool 等。

oracle 的 range partition 到 DB2 的 table partition

下面我們假設 Oracle 數據庫中有一個 range partition 的表,該表的定義如下,下面我們以此表為案例,把該表遷移到 DB2 的 table partition 中。

清單 11.Oracle 中 Range partition 表定義
 CREATE TABLE usertest.sales 
 ( 
 year int, 
 month int 
 ) 
 PARTITION BY RANGE (year, month) 
 (PARTITION p1 VALUES LESS THAN (2009,4) tablespace tbsp1, 
 PARTITION p2 VALUES LESS THAN (2009,7) tablespace tbsp2, 
 PARTITION p3 VALUES LESS THAN (2009,10) tablespace tbsp3, 
 PARTITION p4 VALUES LESS THAN (2010,1) tablespace tbsp4, 
 );

其中 usertest 為該表的 schema, 這裡我們創建了 4 個 partition 分別在 tbsp1、tbsp2、tbsp3、tbsp4 四個表空間內,通過 select 語句查詢出數據集。

圖 4.Oracle 中 Range Partition 表的數據查詢結果集
Oracle 中 Range Partition 表的數據查詢結果集

下面就需要把這個 range partition 的表遷移到 db2 中,首先在 db2 中創建與之對應的 table partition 的表。在 oracle 中比當前日期小的值不包含在相應的 partition 中,如上面 sql 中的,這一點與 db2 不同。其中對應的 db2 中的建表語句如下:

清單 12. DB2 中 Table partition 的表定義
 CREATE TABLE "USERTEST"."SALES"
 ( 
"YEAR" DECFLOAT(16)  , 
"MONTH" DECFLOAT(16)  
 ) 
 PARTITION BY RANGE ("YEAR","MONTH") 
 ( 
 PARTITION P1 STARTING (MINVALUE,MINVALUE) INCLUSIVE ENDING (2009, 4) INCLUSIVE 
 ,PARTITION P2 ENDING (2009, 7) INCLUSIVE 
 ,PARTITION P3 ENDING (2009, 10) INCLUSIVE 
 ,PARTITION P4 ENDING (2010, 1) INCLUSIVE 
 )

在 DB2 中我們也定義了 4 個分區 P1、P2、P3、P4,在做數據遷移時,如果我們用 import、export 做數據的遷入遷出,對比生成的 data 文件我們會發現 oracle 和 db2 的數據格式完全不一樣,因此對於數據規模比較大的表用 import、export 就不太現實,這時我們可以借助 IDMT 來進行表的定義以及數據的導出導入。這裡我們借助 IDMT 來進行數據的導出導入, 其具體的使用說明可參 IDMT 的使用說明 http://www.ibm.com/developerworks/data/library/techarticle/dm-0906datamovement。

其數據導入後,用 datastudio 進行數據查詢的結果。根據查詢結果集的對比可知數據已經完全遷移過來。

圖 5:DB2 中 Table Partition 表的數據查詢結果集
DB2 中 Table Partition 表的數據查詢結果集

Oracle 的 Hash partition 到 DB2 的 DPF

假設在一個 Oracle 數據庫中有一個 Hash Partition 的表定義如下:

清單 13. Oracle 中 Hash table 的表定義
 CREATE TABLE hash_sales 
 ( 
 salesdate date, 
 protype varchar2(20), 
 proname varchar2(20) 

 ) 
 PARTITION BY HASH(salesdate) 
 ( 
 partition p0 tablespace tbhash, 
 partition p1 tablespace tbhash 
 );

 

該表以 hash_part 字段按照 HASH 算法分區,創建了兩個分區 p1 和 p2 分別在表空間 tbsp1 和 tbsp2 中。用 select 語句查詢出其數據結果集:

圖 6.Oracle 中 Hash Partition 表的數據查詢結果集
Oracle 中 Hash Partition 表的數據查詢結果集

根據前面所說,我們可以把該 table 映射到 DB2 的 DPF 上。如果當前 DB 已經創建好了 DPF,那麼我就直接創建 table 即可,但是做 migration 很多時候都需要自己創建邏輯分區,我們將按照下面的步驟創建 DPF、Table space 以及 Table。

  • 用 db2start 添加 partition

    我們可以用 db2start 來創建 partition,其命令格式如下:

    db2start dbpartitionnum PARTITIONNUM add dbpartitionnum hostname <HOSTNAME> port <PORTNUM> without tablespaces

    這裡我們已經有了一個 partition 0,我們再創建一個 partition 1。

    db2start dbpartitionnum 1 add dbpartitionnum n4shost port 1 withoust tablespaces

  • 創建 partition group

    partition 添加完成之後,下面就需要為 partition 創建 partition group。其命令格式如下:

    create database partition group <GROUP NAME> on dbpartitionnums(<num>,<num> … )

    這裡我們創建的 group 為 grouphash。

    Create database partition group grouphash on dbpartitionnums(0,1)
  • 創建 tablespace

    在該 partition group 中創建 tablespace。其命令格式如下:

    Create tablespace <Tablespace name> in database partition group <PARTITION GROUP NAME>

    這裡我們創建表空間 tphash:

    Create tablespace tphash in database partition group grouphash

  • 創建 table

    在 tbptest 中創建與 oracle 對應的 table,其 sql 語句如下:

    清單 14. DB2 中與之映射的 DPF table
     create table hash_sales( 
     salesdate date, 
     protype varchar(20), 
     proname varchar(20) 
     ) 
     in tphash  
     distribute by hash(salesdate)

完成了表的創建,下面就是數據的導出與導入,與上一節相同我們同樣可以采用工具 IDMT 來實現。但是在本次實驗中的數據很少,因此這裡我們就直接用 import 來實現數據的導入。數據導入完成之後通過 clp 查詢的數據結果如下圖所示。

圖 7.db2 中映射的 DPF 表查詢結果集
db2 中映射的 DPF 表查詢結果集

總結

本文分別對 Oracle 和 DB2 的分區模式進行了概述,並且對兩種數據的分區方式進行對比,介紹了 Oracle 中的簡單分區在 DB2 中我們可以采用什麼樣的分區方式與之映射。對於 Oracle 中的復合分區,本文也對 Range-list 和 Range-hash 進行了介紹以及提出了在 DB2 中與之映射的方案。同時我們也對 oracle 中的 range partition 和 hash partition 的表如何遷移到 db2 中進行了簡單的描述,並且提供了相應的方法。

總之,本文對 oracle 的 partition 遷移到 db2 提供了一個整體的映射方案並且提供了一些簡單的數據遷移方法,對於復雜的復合分區還有待於完善

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved