今天看啥
热点:

数据库 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 提供了一个整体的映射方案并且提供了一些简单的数据迁移方法,对于复杂的复合分区还有待于完善

www.bkjia.comtruehttp://www.bkjia.com/DB2/622084.htmlTechArticle数据库 Partitioning 概述 当数据库表中的数据不断增大,必然会导致数据的查询速度降低,从而应用程序的性能就会下降,这时就应该考虑对...

相关文章

相关搜索: ORACLE 迁移 DB2:

帮客评论

视觉看点