一、分区表管理
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; |