暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【SQL杂货铺】-分区表管理

原创 闫伟 2023-01-19
535


一、分区表管理

1、创建分区表

分区表分为四类:1、范围分区表 2、列表分区表 3、哈希分区表 4、组合分区表

--1、范围分区表

CREATE TABLE range_example(

     range_key_column DATE,

     DATA VARCHAR2(20),

     ID integer

 ) PARTITION BY RANGE(range_key_column)

 (

     PARTITION part01 VALUES LESS THAN (TO_DATE('2020-04-1 00:00:00','yyyy-mm-dd hh24:mi:ss')) TABLESPACE tbs01,

     PARTITION part02 VALUES LESS THAN (TO_DATE('2020-05-1 00:00:00','yyyy-mm-dd hh24:mi:ss')) TABLESPACE tbs02,

     PARTITION part03 VALUES LESS THAN (TO_DATE('2020-06-1 00:00:00','yyyy-mm-dd hh24:mi:ss')) TABLESPACE tbs03

);

 

--2、列表分区表

CREATE TABLE list_example(

     dname VARCHAR2(10),

     DATA VARCHAR2(20)

)PARTITION BY LIST(dname)

(

      PARTITION part01 VALUES('ME','PE','QC','RD'),

      PARTITION part02 VALUES('SMT','SALE')

);

--3、哈希分区表

CREATE TABLE hash_example(

      hash_key_column DATE,

      DATA VARCHAR2(20)

) PARTITION BY HASH(hash_key_cloumn)

(

     PARTITION part01 ,

     PARTITION part02

);

--4、组合分区表

--注意subpartitions 2 并不是指定subpartition的个数一定为2,实际上每个分区的子分区个数可以不同。subpartitions 关键字的作用到底是什么?如果不指定subpartition的具体明细,则系统按照subpartitions的值指定subpartition的个数生成子分区,名称由系统定义 。

CREATE TABLE range_hash_example(

 range_column_key DATE,

 hash_column_key INT,

 DATA VARCHAR2(20)

)

PARTITION BY RANGE(range_column_key)

SUBPARTITION BY HASH(hash_column_key) SUBPARTITIONS 2

(

   PARTITION part_1 VALUES LESS THAN (TO_DATE('2020-04-01','yyyy-mm-dd'))(

      SUBPARTITION part_1_sub_1,

      SUBPARTITION part_1_sub_2,

      SUBPARTITION part_1_sub_3

   ),

   PARTITION part_2 VALUES LESS THAN (TO_DATE('2020-05-01','yyyy-mm-dd'))(

      SUBPARTITION part_2_sub_1,

      SUBPARTITION part_2_sub_2

   )

);

 

 

 

 

2、分区维护

1.1、添加分区

 

--1、给SALES表添加一个P3分区

ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));

注意:以上添加的分区界限应该高于最后一个分区界限。

--2、给SALES表的P3分区添加了一个P3SUB1子分区

ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');

1.2、删除分区

1、删除了P3表分区:

ALTER TABLE SALES DROP PARTITION P3;

2、删除了P4SUB1子分区:

ALTER TABLE SALES DROP SUBPARTITION P4SUB1;

注意:如果删除的分区是表中唯一的分区,那么此分区将不能被删除,要想删除此分区,必须删除表。

1.3、截断分区

截断某个分区是指删除某个分区中的数据,并不会删除分区,也不会删除其它分区中的数据。当表中即使只有一个分区时,也可以截断该分区。

--1、截断分区:

ALTER TABLE SALES TRUNCATE PARTITION P2;

--2、截断子分区:

ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;

1.4、合并分区

合并分区是将相邻的分区合并成一个分区,结果分区将采用较高分区的界限,值得注意的是,不能将分区合并到界限较低的分区。

实现P1 P2分区的合并:

ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2;

1.5、拆分分区

拆分分区将一个分区拆分两个新分区,拆分后原来分区不再存在。注意不能对HASH类型的分区进行拆分。

ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);

1.6、接合分区(coalesca)

结合分区是将散列分区中的数据接合到其它分区中,当散列分区中的数据比较大时,可以增加散列分区,然后进行接合,值得注意的是,接合分区只能用于散列分区中。

ALTER TABLE SALES COALESCA PARTITION;

1.7、重命名表分区

--将P21更改为P2

ALTER TABLE SALES RENAME PARTITION P21 TO P2;

 

3、查询表上有多少分区

SELECT * FROM useR_TAB_PARTITIONS WHERE TABLE_NAME='tableName'

4、显示分区表信息

--显示数据库所有分区表的信息

select * from DBA_PART_TABLES

--显示当前用户可访问的所有分区表信息

select * from ALL_PART_TABLES

--显示当前用户所有分区表的信息

select * from USER_PART_TABLES

5、显示表分区信息

-- 显示数据库所有分区表的详细分区信息

select * from DBA_TAB_PARTITIONS

--显示当前用户可访问的所有分区表的详细分区信息:

select * from ALL_TAB_PARTITIONS

--显示当前用户所有分区表的详细分区信息:

select * from USER_TAB_PARTITIONS

 

6、显示子分区信息

--显示子分区信息 显示数据库所有组合分区表的子分区信息:

select * from DBA_TAB_SUBPARTITIONS

--显示当前用户可访问的所有组合分区表的子分区信息:

select * from ALL_TAB_SUBPARTITIONS

--显示当前用户所有组合分区表的子分区信息:

select * from USER_TAB_SUBPARTITIONS

7、显示分区列

-- 显示数据库所有分区表的分区列信息:

select * from DBA_PART_KEY_COLUMNS

--显示当前用户可访问的所有分区表的分区列信息:

select * from ALL_PART_KEY_COLUMNS

--显示当前用户所有分区表的分区列信息:

select * from USER_PART_KEY_COLUMNS

8、显示子分区列

--显示数据库所有分区表的子分区列信息:

select * from DBA_SUBPART_KEY_COLUMNS

--显示当前用户可访问的所有分区表的子分区列信息:

select * from ALL_SUBPART_KEY_COLUMNS

--显示当前用户所有分区表的子分区列信息:

select * from USER_SUBPART_KEY_COLUMNS

 

9、普通表转换成分区表

将普通表转换成分区表有4种方法:

1)Export/import method

2)Insert with a subquery method

3)Partition exchange method

4)DBMS_REDEFINITION

在线重定义能保证数据的一致性,在大部分时间内,表都可以正常进行DML操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性,对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约束,可以做到切换完成后不再需要任何额外的管理操作。

关于DBMS_REDEFINITION的介绍,参考官方连接:

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_redefi.htm#CBBFDJBC

--1、创建表

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);

 

--2、插入数据

SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;

SQL> COMMIT;

 

--3、在线重定义的表自行验证,看该表是否可以重定义,

SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(user, 'T', DBMS_REDEFINITION.CONS_USE_PK);

 (如果没有定义主键会提示以下错误信息

 begin dbms_redefinition.can_redef_table(user,'pft_party_profit_detail'); end;

 ORA-12089: cannot online redefine table "OFSA"."PFT_PARTY_PROFIT_DETAIL" with no primary key

 ORA-06512: at "SYS.DBMS_REDEFINITION", line 8

 ORA-06512: at "SYS.DBMS_REDEFINITION", line 247

 ORA-06512: at line 1

 

 出错了, 该表上缺少主键,为该表建主键。再执行验证。

 SQL> alter table t add constraint pk_t primary key(id);

 Table altered)

 

--4、建个和源表表结构一样的分区表,作为中间表。按日期范围分区

SQL> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)

     (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),

     PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),

     PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),

     PARTITION P4 VALUES LESS THAN (MAXVALUE));

 这里值得注意的一个问题是:PARTITION P4 VALUES LESS THAN (MAXVALUE))是把所有剩下的数据分在一个区里,如果你想一个月建一个分区,那最好写成这样,提前建好

 

 SQL> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)

     (PARTITION P20070201 VALUES LESS THAN (TO_DATE('2007-2-1', 'YYYY-MM-DD')),

     PARTITION P20070301 VALUES LESS THAN (TO_DATE('2005-3-1', 'YYYY-MM-DD')),

     PARTITION P20070401 VALUES LESS THAN (TO_DATE('2005-4-1', 'YYYY-MM-DD')),

     PARTITION P20070501 VALUES LESS THAN (TO_DATE('2005-5-1', 'YYYY-MM-DD')),  

     PARTITION P20070601 VALUES LESS THAN (TO_DATE('2005-6-1', 'YYYY-MM-DD')));  

 

--5、执行表的在线重定义:

SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW');

 

--6、执行把中间表的内容和数据源表进行同步。

SQL>execute dbms_redefinition.sync_interim_table(user,'t','t_new');

 

--7、执行结束在线定义过程

SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(user, 'T', 'T_NEW');

 

--8、查看数据字典,可以看到改表已经成为了分区表。

SQL> SELECT COUNT(*) FROM T;

  COUNT(*)

----------

      6264

SQL> SELECT COUNT(*) FROM T PARTITION (P2);

  COUNT(*)

----------

      6246

SQL> SELECT COUNT(*) FROM T PARTITION (P3);

  COUNT(*)

----------

 

至此普通表转为分区操作完成

 

--9、如果执行在线重定义的过程中出错

可以在执行dbms_redefinition.start_redef_table之后到执行dbms_redefinition.finish_redef_table之前的时间里执行:

DBMS_REDEFINITION.abort_redef_table(user, 't', 't_new')以放弃执行在线重定义。

 

--10、如果出现以下错误:

SQL> exec dbms_redefinition.can_redef_table(user, 't');

BEGIN dbms_redefinition.can_redef_table(user, 't'); END;

 

*

ERROR at line 1:

ORA-12091: cannot online redefine table "user"."t" with

materialized views

ORA-06512: at "SYS.DBMS_REDEFINITION", line 137

ORA-06512: at "SYS.DBMS_REDEFINITION", line 1478

ORA-06512: at line 1

 

用这句删除materialized view 即可继续进行

drop materialized view log on <tablename>;

drop materialized view log on t;

    OR drop materialized t;

 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论