1. 概念 表分区允许用户将一个表分为多个分区; 用户可以执行查询,只访问表中的特定分区; 将不同的分区存储在不同的磁盘,提高访问性能和安全性; 可以独立地备份和恢复每个分区。 2. 传统的表分区 传统表分区指的是 oracle 10g 及之前版本的表分区。传统的表分区有四种类型,分别为范围分区、散列分区、列表分区和复合分区四种。我们可以使用如下语句查看指定表的分区信息:
1 select  * from  user_tab_partitions u where  u.table_name = '全大写表名' ;
2.1 范围分区 2.1.1 含义 范围分区是以表中的一个列或一组列的值的范围分区。范围分区的缺点很明显,即可能存在大量相同范围的记录存在特定的分区的现象,从而导致分区分配不均的情况。
2.1.2 语法 语法如下:
1 2 3 4 5 6 7 PARTITION BY RANGE (column_name) (   PARTITION part1 VALUES  LESS  THAN (range1),   PARTITION  part2 VALUES  LESS  THAN (range2),   ...   [PARTITION  partN VALUES  LESS  THAN (MAXVALUE)] ); 
2.1.3 示例 创建一个产品表,按照价格字段 price 的范围分为三个分区,具体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 create  table  product(pno number , price number )partition  by  range (price) (    partition  p1 values  less  than (1000 ),      partition  p2 values  less  than (2000 ),      partition  p3 values  less  than (maxvalue)  ); insert  into  product values (1 , 200 );insert  into  product values (2 , 1000 );insert  into  product values (3 , 2020 );SQL> select * from product partition(p1);        PNO      PRICE          1        200 SQL> select * from product partition(p2);        PNO      PRICE          2       1000 SQL> select * from product partition(p3);        PNO      PRICE          3       2020 
提示:对表建立分区之后,查询语句会发生变化,即要对某个分区进行查询的时候需要在后面带 partition;而对于更新删除操作则仍然保持普通的写法。 
2.2 散列分区 2.2.1 含义 散列分区允许用户对不具有逻辑范围的数据进行分区,通过在分区键上执行HASH函数决定存储的分区。不同于范围分区,散列分区可以有效地避免分区数据分配不均的情况发生,散列分区可以将数据平均地分布到不同的分区中。
2.2.2 语法 1 2 3 4 5 6 7 8 9 10 PARTITION BY HASH (column_name) PARTITIONS number_of_partitions; 或 PARTITION BY HASH (column_name) ( PARTITION part1 [TABLESPACE tbs1],   PARTITION part2 [TABLESPACE tbs2],   ...   PARTITION partN [TABLESPACE tbsN] ); 
2.2.3 示例 创建一个 person 表,按人员的姓名分为四个散列分区,具体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 create  table  person(name  varchar2(50 ), age number )partition  by  hash (name )partitions  4 ;create  table  person(name  varchar2(50 ), age number )partition  by  hash (name ) (    partition  p1,     partition  p2,     partition  p3,     partition  p4 ) insert  into  person values ('张三' , 22 );insert  into  person values ('李四' , 36 );insert  into  person values ('王五' , 45 );insert  into  person values ('赵六' , 12 );SQL> select * from person partition(p1); NAME                                                      AGE SQL> select * from person partition(p2); NAME                                                      AGE 张三                                                       22 王五                                                       45 SQL> select * from person partition(p3); NAME                                                      AGE 李四                                                       36 SQL> select * from person partition(p4); NAME                                                      AGE 赵六                                                       12 
2.3 列表分区 2.3.1 含义 列表分区允许用户将不相关的数据组织在一起。列表分区支持对字段的具体值进行分区,不同于范围限定一个范围,列表分区是限定在具体的值。
2.3.2 语法 1 2 3 4 5 6 7 PARTITION BY LIST (column_name) (   PARTITION part1 VALUES  (values_list1),   PARTITION  part2 VALUES  (values_list2),   ...   PARTITION  partN VALUES  (DEFAULT ) ); 
2.3.3 示例 创建一个 person 表,并按地市字段 city 对表进行分区,具体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 create  table  person(name  varchar2(50 ), city varchar2(20 ))partition  by  list (city)(    partition  p1 values  ('广州' ),     partition  p2 values  ('深圳' ),     partition  p3 values  (default ) ); insert  into  person values ('李四' , '深圳' );insert  into  person values ('李四' , '广州' );insert  into  person values ('李四' , '南昌' );SQL> select * from person partition(p1); NAME                                               CITY 李四                                               广州 SQL> select * from person partition(p2); NAME                                               CITY 李四                                               深圳 SQL> select * from person partition(p3); NAME                                               CITY 李四                                               南昌 
2.4 复合分区 2.4.1 含义 复合分区指的是范围分区与散列分区或列表分区的组合,即复合只存在两种组合方式:范围分区 + 散列分区与范围分区 + 列表分区。
2.4.2 语法 1 2 3 4 5 6 7 8 9 10 PARTITION BY RANGE (column_name1) SUBPARTITION BY HASH (column_name2) SUBPARTITIONS number_of_partitions (   PARTITION part1 VALUES  LESS  THAN (range1),   PARTITION  part2 VALUES  LESS  THAN (range2),   ...   PARTITION  partN VALUES  LESS  THAN (MAXVALUE) ); 
2.4.3 示例 创建一个 student 表并进行复合分区,先按 sno 进行范围分区,在对 sname 进行散列分区,具体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 create  table  student(sno number , sname varchar2(50 ))partition  by  range (sno)subpartition  by  hash (sname)subpartitions  4  (    partition  p1 values  less  than (1000 ),     partition  p2 values  less  than (2000 ),     partition  p3 values  less  than (3000 ),     partition  p4 values  less  than (maxvalue) ); insert  into  student values (20 , '李四' );insert  into  student values (2020 , '张三' );insert  into  student values (3020 , '王五' );SQL> select * from student partition(p1);        SNO SNAME         20 李四 SQL> select * from student partition(p2);        SNO SNAME SQL> select * from student partition(p3);        SNO SNAME       2020 张三 SQL> select * from student partition(p4);        SNO SNAME       3020 王五 
3. 11g 新增表分区 3.1 引用分区 3.1.1 含义 引用分区是基于由外键引用父表的分区的方法,它依赖已有的父表子表的关系,子表通过外键关联到父表,进而继承了父表的分区方式而不需自己创建,子表还继承了父表的维护操作。
主表是无论是范围、散列还是列表分区,子表都是引用分区。
3.1.2 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 create  table  father(    fid number  primary key ,     fname varchar2(50 ) ) partition  by  hash (fname) (    partition  p1,     partition  p2 ); create  table  son(    sid  number  primary key ,     sname varchar2(50 ),     fid number  not  null ,      constraint  fk_fid foreign  key (fid) references  father(fid) ) partition  by  reference (fk_fid); SQL> select TABLE_NAME, COMPOSITE, PARTITION_NAME  from user_tab_partitions; TABLE_NAME                     COMPOSITE PARTITION_NAME FATHER                         NO        P1 FATHER                         NO        P2 SON                            NO        P1 SON                            NO        P2 insert  into  father values (1 , '张三' );insert  into  father values (2 , '李四' );insert  into  father values (3 , '王五' );insert  into  son values (11 , '张三三' , 1 );insert  into  son values (22 , '李四四' , 2 );insert  into  son values (33 , '王五五' , 3 );SQL> select * from father partition(p1);        FID FNAME          2 李四 SQL> select * from father partition(p2);        FID FNAME          1 张三          3 王五 SQL> select * from son partition(p1);        SID SNAME                                                     FID         22 李四四                                                      2 SQL> select * from son partition(p2);        SID SNAME                                                     FID         11 张三三                                                      1         33 王五五                                                      3 
3.2 间隔分区 3.2.1 含义 间隔分区可以完全自动地根据间隔阈值创建范围分区,它是范围分区的扩展 。间隔分区在数据仓库中有广泛的应用。
3.2.2 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 create  table  sale_detail (    sale_detail_id number ,     product_id number ,     quantity number ,     sale_date date  ) partition  by  range (sale_date) interval  (numtoyminterval(1 , 'MONTH' )) (          partition  p_201006 values  less  than  (to_date ('20200601' , 'yyyymmdd' )) ); SQL> select TABLE_NAME, PARTITION_NAME, HIGH_VALUE from user_tab_partitions where table_name = 'SALE_DETAIL'; TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE SALE_DETAIL                    P_201006                       TO_DATE(' 2020-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA insert  into  sale_detail values  (1 , 11 , 10 , to_date ('20200501' , 'yyyymmdd' )); insert  into  sale_detail values  (2 , 22 , 20 , to_date ('20200711' , 'yyyymmdd' )); insert  into  sale_detail values  (3 , 33 , 30 , to_date ('20200805' , 'yyyymmdd' )); insert  into  sale_detail values  (3 , 33 , 30 , to_date ('20200803' , 'yyyymmdd' )); insert  into  sale_detail values  (4 , 44 , 40 , to_date ('20201212' , 'yyyymmdd' )); insert  into  sale_detail values  (5 , 55 , 50 , to_date ('20200913' , 'yyyymmdd' )); 
3.3 虚拟列分区 3.3.1 含义 基于虚拟列的分区:把分区建立在某个虚拟列上,即建立在函数或表达式的计算结果上,来完成某种任务。
3.3.2 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 create  table  sale(    sale_id number  primary key ,     product_id number ,     price number ,     quantity number ,     sale_date date ,     total_price as  (price * quantity) virtual   ) partition  by  range (total_price)(    partition  p_1000 values  less  than (1000 ),     partition  p_2000 values  less  than (2000 ),     partition  p_max values  less  than (maxvalue) ); insert  into  sale(sale_id, product_id, price, quantity, sale_date) values (1 , 11 , 10 , 5 , sysdate );insert  into  sale(sale_id, product_id, price, quantity, sale_date) values (2 , 22 , 2000 , 5 , sysdate );
3.4 系统分区 3.4.1 含义 系统分区不指定分区列,由ORACLE来完成分区的控制和管理,它没有了范围分区或列表分区的界限。
3.4.2 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 create  table  person (    id  number ,     name  varchar2(20 ),     address varchar2(20 ) ) partition  by  system  (    partition  p1, partition  p2, partition  p3 ) insert  into  person partition (p1) values  (1 , '张三' , '北京' );insert  into  person partition (p2) values  (2 , '李四' , '广州' );insert  into  person partition (p3) values  (3 , '王五' , '南宁' );
4. 维护分区 4.1 添加分区 在最后一个分区之后添加新分区
1 2 ALTER  TABLE  SALES ADD  PARTITION  P4 VALUES  LESS  THAN  (4000 );
4.2 删除分区 删除一个指定的分区,分区的数据也随之删除,不保留分区结构
1 2 ALTER  TABLE  SALES DROP  PARTITION  P4;
4.3 截断分区 删除指定分区中的所有记录,保留分区结构
1 2 ALTER  TABLE  SALES TRUNCATE  PARTITION  P3;
4.4 合并分区 将范围分区或复合分区的两个相邻分区连接起来
1 2 ALTER  TABLE  SALES MERGE  PARTITIONS  S1, S2 INTO  PARTITION  S2;
4.5 拆分分区 将一个大分区中的记录拆分到两个分区中
1 2 ALTER  TABLE  SALES SPLIT  PARTITION  P2 AT  (1500 ) INTO  (PARTITION  P21, PARTITION  P22);