ITPub博客

首页 > 数据库 > Oracle > oracle分区表

oracle分区表

原创 Oracle 作者:王小库 时间:2016-06-23 10:42:44 0 删除 编辑
  分区表是在oracle中经常使用到,其作用是巨大的。当表的数据增大到一定程度时(超过2gb),可以考虑使用。其还是一张表,不过可以将表划分成不同的分区,不同的分区可以存放在不同的磁盘路劲下,这样当访问表的不同分区时,可以只扫描特定的分区,降低了I/O,同样不同的分区也便于管理和维护表的数据。
   分区表的分类 
1:范围分区(range):根据数据的大小范围来划分表的分区;
         WANG1 @db>create table range_table (id int,iname varchar2(20) )
        2       partition by range(id) (
        3       partition p1 values less than(10),
        4       partition p2 values less than(20)
        5  );
       增加分区:WANG1 @db>alter table range_table add partition p3 values less than (maxvalue);分区分区最好使用maxvalus来限制他的上限,这样就不会造成数据插入时没有相对应的分区。
      查看分区的信息:WANG1 @db>select * from range_table partition(p1);
     更新分区:跨分区更新时,要先使得行移动才行,否则会报错。WANG1 @db>alter table range_table enable row movement; 
2:哈希分区(hash):将数据均衡的分配到每一个分区。
       WANG1 @db>create table hash_table(id int,iname varchar2(2))
         2       partition by hash(id) (
         3       partition p1 ,
         4       partition p2);
3:列表分区(list):将关联不是很大的数据分区在一起。例如:东南西北
   WANG1 @db>create table list_table(id int ,iname varchar2(20) )
      2       partition by list(iname) (
      3       partition dong values('aa'),
      4       partition xi   values('cc'),
      5       partition nan  values('dd'),
      6       partition bei  values('ee') 
      7  );
4:复合分区:将范围分区和哈希分区或者范围分区和列表分区结合,10G只支持range-hash,range_list,而11G以后就支持range,interval,list和range,list,hash九中复合分区。
    WANG1 @db>create table sub_table(id int,iname varchar2(20) )
     2       partition by range(id)
  3       subpartition by hash(iname)
  4       subpartitions 4 (
  5       partition p1 values less than(10),
  6       partition p2 values less than(20),
  7       partition p3 values less than(maxvalue)
  8  );
以上四种分区应用较为广泛,一下的四种是oracle针对不同要求在11G提出来的分区。
5:系统分区(system):在建立表的时候不需要制定分区列,可以在插入的时候指定相应的数据插入到相对应的分区中去。
   WANG1 @db>create table system_table(id int,iname varchar2(20))
     2       partition by system (
     3       partition p1, 
     4       partition p2);
     插入的时候指定相对应的分区
    WANG1 @db>insert into system_table partition(p1) values(1,'aa');
 6:间隔分区(interval):是range分区的一个扩展,可以自动生成分区。
   WANG1 @db>create table interval_sales(s_id int,d_1 date)
    2       partition by range(d_1)
    3       interval(numtoyminterval(1,'MONTH'))
    4  ( partition p1 values less than(to_date('2016-06-01','yyyy-mm-dd'))
    5  );
   插入数据,超过了一个月就自动生成一个分区。
  WANG1 @db>insert into interval_sales values(1,to_date('2016-05-11','yyyy-mm-dd'));
   WANG1 @db>insert into interval_sales values(2,to_date('2016-06-11','yyyy-mm-dd'));
   查询增加了一个分区
WANG1 @db>select segment_name,partition_name,segment_type from user_segments;
INTERVAL_SALES                                                                    P1                             TABLE PARTITION
INTERVAL_SALES                                                                    SYS_P53                        TABLE PARTITION
7:引用分区:当有主外键约束的时候,字表没有父亲表的分区列是也可以建立基于该列的分区。带有外检约束的列要加上非空约束,否则不能建立应用分区。
WANG1 @db>create table father_table(id int,iname varchar2(20),constraint pri_id primary key(id)) 
  2         partition by range(id)(
  3         partition p1 values less than(10),
  4         partition p2 values less than(maxvalue) 
  5  );
WANG1 @db>create table son_table (sid int not null,sname varchar2(20),constraint re_sid foreign key(sid) references  father_table(id) )
  2  partition by reference(re_sid);
 子表也有对应的分区
WANG1 @db>select table_name,partition_name,high_value from user_tab_partitions
  2       where table_name in ('FATHER_TABLE','SON_TABLE');
TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE
------------------------------ ------------------------------ --------------------------------------------------------------------------------
FATHER_TABLE                   P1                             10
FATHER_TABLE                   P2                             MAXVALUE
SON_TABLE                        P1
SON_TABLE                        P2
WANG1 @db>insert into father_table values(1,'aa');
WANG1 @db>insert into father_table values(100,'bb');
字表插入相对应的数据,会自动插入到相对应的子表的分区中,例如:插入SID为1的话,就会在P1分区。插入SID为100的话就在P2分区。
WANG1 @db>insert into son_table values(1,'cc');
WANG1 @db>select * from son_table partition(p1);
       SID SNAME
---------- --------------------
         1 cc

WANG1 @db>select * from son_table partition(p2);


       SID SNAME
---------- --------------------
       100 dd

 8:虚拟列分区:虚拟列分区是建立在虚拟列上的分区,所谓的虚拟列就是算术表达式,其不实际存放数据,不能直接被UPDATE。
WANG1 @db>create table xuni_table(
  2       id int,
  3       sid int,
  4       iname varchar2(20),
  5       sun_id as (id+sid) )
  6       partition by range(sun_id)(
  7       partition p1 values less than(20),
  8       partition p2 values less than(maxvalue))
  9      enable row movement;
联机重定义:oracle在建立好的表之后是不能直接更改成为分区表,但是提供了联机重定义功能,将表转换成分区表。
现有表test,需要将其转换成分区表,并且将IDAY列去掉
WANG1 @db>create index ind_test on test(iname);
WANG1 @db>select * from test;

        ID INAME                IDAY
---------- -------------------- ------------
         1 aa                   01-JAN-11
        11 bb                   01-JAN-12
        21 cc                   01-JAN-13
        31 dd                   01-JAN-14
        41 dd                   01-JAN-15
        51 ee                   01-JAN-16
1:检查表是否有联机重定义功能
SYS @db>set serverout on
SYS @db>begin 
  2     DBMS_REDEFINITION.CAN_REDEF_TABLE('WANG1','TEST');
  3     end;
  4  /

2:创建临时表
ANG1 @db>create table test_temp(id int,iname varchar2(20))
  2      partition by range(id)(
  3      partition p1 values less than(30),
  4      partition p2 values less than(maxvalue)
  5  );
3:启动联机重定义功能
SYS @db>begin
  2  dbms_redefinition.start_redef_table('WANG1','TEST','TEST_TEMP',
  3   'id id,
  4    iname iname');
  5  end;
  6  /
这个时候临时表的数据是过来了,分区也建立好了,但是约束,函数是没有的,
WANG1 @db>select * from test_temp partition(p1);
     
ID INAME
---------- --------------------
         1 aa
        11 bb
        21 cc
WANG1 @db>select index_name from user_indexes where table_name='TEST_TEMP';
no rows selected
WANG1 @db>select constraint_name,table_name from user_constraints where table_name='TEST_TEMP';
no rows selected
4:复制依赖对象,将原理表的所有属性过继过来。
DECLARE
  log_error int;
BEGIN
  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
uname   =>'WANG1',
orig_table  =>'TEST',
int_table  =>'TEST_TEMP',
num_errors =>log_error
);
END;
/
5:完成所有操作,其实就是将临时表改成正式表。
SQL> EXECUTE dbms_redefinition.finish_redef_table('scott','emp1','emp1_temp');

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31365320/viewspace-2120801/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2016-06-22

  • 博文量
    1
  • 访问量
    1496