一 创建和使用分区表
1.范围分区(RANGE)
2)所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。
3)在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。这个值高于其它分区中的任何分区键的值,也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。
CREATE TABLE CUSTOMER ( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, FIRST_NAME<span style="white-space:pre"> </span>VARCHAR2(30) NOT NULL, LAST_NAME<span style="white-space:pre"> </span>VARCHAR2(30) NOT NULL, PHONE<span style="white-space:pre"> </span>VARCHAR2(15) NOT NULL, EMAIL<span style="white-space:pre"> </span>VARCHAR2(80), STATUS<span style="white-space:pre"> </span>CHAR(1) ) PARTITION BY RANGE (CUSTOMER_ID) ( PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE CUS_TS01, PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE CUS_TS02 );
例二:按时间划分
CREATE TABLE ORDER_ACTIVITIES ( ORDER_ID NUMBER(7) NOT NULL, ORDER_DATE DATE, TOTAL_AMOUNT NUMBER, CUSTOTMER_ID NUMBER(7), PAID CHAR(1) ) PARTITION BY RANGE (ORDER_DATE) ( PARTITION ORD_ACT_PART01 VALUES LESS THAN (TO_DATE('01- MAY -2003','DD-MON-YYYY')) TABLESPACEORD_TS01, PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUN-2003','DD-MON-YYYY')) TABLESPACE ORD_TS02, PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUL-2003','DD-MON-YYYY')) TABLESPACE ORD_TS03 );
例三:MAXVALUE
CREATE TABLE RANGETABLE ( idd INT PRIMARY KEY , iNAME VARCHAR(10), grade INT ) PARTITION BY RANGE (grade) ( PARTITION part1 VALUES LESS THEN (1000) TABLESPACE Part1_tb, PARTITION part2 VALUES LESS THEN (MAXVALUE) TABLESPACE Part2_tb ); --——在表上执行查询 select * from RANGETABLE; --——在表分区上执行查询 select * from RANGETABLE partition(part1);
2.列表分区(LIST)
该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。创建一个按字段数据列表固定可枚举值分区的表。插入记录分区字段的值必须在列表中,否则不能被插入。
例一:
<span style="font-size: 12px;"><span style="font-family:SimSun;">CREATE TABLE PROBLEM_TICKETS ( PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY, DESCRIPTION VARCHAR2(2000), CUSTOMER_ID NUMBER(7) NOT NULL, DATE_ENTERED DATE NOT NULL, STATUS VARCHAR2(20) ) PARTITION BY LIST (STATUS) ( PARTITION PROB_ACTIVE VALUES ('ACTIVE') TABLESPACE PROB_TS01, PARTITION PROB_INACTIVE VALUES ('INACTIVE') TABLESPACE PROB_TS02 );</span></span><span style="font-family:georgia, verdana, Arial, helvetica, sans-seriff;font-size:14px;"> </span>
例二:
<span style="font-family:SimSun;font-size:12px;">CREATE TABLE ListTable ( id INT PRIMARY KEY , name VARCHAR (20), area VARCHAR (10) ) PARTITION BY LIST (area) ( PARTITION part1 VALUES ('guangdong','beijing') TABLESPACE Part1_tb, PARTITION part2 VALUES ('shanghai','nanjing') TABLESPACE Part2_tb );</span>
3.哈希分区(散列分区)(HASH)
CREATE TABLE HASH_TABLE ( COL NUMBER(8), INF VARCHAR2(100) ) PARTITION BY HASH (COL) ( PARTITION PART01 TABLESPACE HASH_TS01, PARTITION PART02 TABLESPACE HASH_TS02, PARTITION PART03 TABLESPACE HASH_TS03 )
简写:
CREATE TABLE emp ( empno NUMBER (4), ename VARCHAR2 (30), sal NUMBER ) PARTITION BY HASH (empno) PARTITIONS 8 STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);
hash分区最主要的机制是根据hash算法来计算具体某条纪录应该插入到哪个分区中,hash算法中最重要的是hash函数,Oracle中如果你要使用hash分区,只需指定分区的数量即可。建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。
4.组合分区(RANGE-LIST 和 RANGE-HASH)
CREATE TABLE SALES ( PRODUCT_ID VARCHAR2(5), SALES_DATE DATE, SALES_COST NUMBER(10), STATUS VARCHAR2(20) ) PARTITION BY RANGE(SALES_DATE) SUBPARTITION BY LIST (STATUS) ( PARTITION P1 VALUES LESS THAN(TO_DATE('2003-01-01','YYYY-MM-DD'))TABLESPACE rptfact2009 ( SUBPARTITION P1SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009, SUBPARTITION P1SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009 ), PARTITION P2 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE rptfact2009 ( SUBPARTITION P2SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009, SUBPARTITION P2SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009 ) )
2)基于范围分区和散列分区,表首先按某列进行范围分区,然后再按某列进行散列分区。
create table dinya_test ( transaction_id number primary key, item_id number(8) not null, item_description varchar2(300), transaction_date date ) partition by range(transaction_date) subpartition by hash(transaction_id) subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03) ( partition part_01 values less than(to_date(‘2006-01-01','yyyy-mm-dd')), partition part_02 values less than(to_date(‘2010-01-01','yyyy-mm-dd')), partition part_03 values less than(maxvalue) );
CREATE TABLE range_hash_example( range_column_key int, hash_column_key INT, DATA <span style="white-space:pre"> </span>VARCHAR2(20) ) PARTITION BY RANGE(range_column_key) SUBPARTITION BY HASH(hash_column_key) SUBPARTITIONS 2 ( PARTITION part_1 VALUES LESS THAN (100000000) ( SUBPARTITION part_1_sub_1, SUBPARTITION part_1_sub_2, SUBPARTITION part_1_sub_3 ), PARTITION part_2 VALUES LESS THAN (200000000) ( SUBPARTITION part_2_sub_1, SUBPARTITION part_2_sub_2 ) );
--注: subpartitions 2 并不是指定subpartition的个数一定为2,实际上每个分区的子分区个数可以不同。如果不指定subpartition的具体明细,则系统按照subpartitions的值指定subpartition的个数生成子分区,名称由系统定义 。
二 有关分区表的维护操作
1.添加分区
ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));
注意:以上添加的分区界限应该高于最后一个分区界限。
以下代码给SALES表的P3分区添加了一个P3SUB1子分区
ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');
-- range partitioned table ALTER TABLE range_example ADD PARTITION part04 VALUES LESS THAN (TO_DATE('2008-10-1 00:00:00','yyyy-mm-ddhh24:mi:ss')); --list partitioned table ALTER TABLE list_example ADD PARTITION part04 VALUES('TE'); --Adding Values for a List Partition ALTER TABLE list_example MODIFY PARTITION part04 ADD VALUES('MIS'); --Dropping Values from a List Partition ALTER TABLE list_example MODIFY PARTITION part04 DROP VALUES('MIS'); --hash partitioned table ALTER TABLE hash_example ADD PARTITION part03; --增加subpartition ALTER TABLE range_hash_example MODIFY PARTITION part_1 ADD SUBPARTITION part_1_sub_4; 注:hash partitioned table新增partition时,现有表的中所有data都有重新计算hash值,然后重新分配到分区中,所以被重新分配的分区的indexes需要rebuild 。
2.删除分区
ALTER TABLE SALES DROP PARTITION P3; ALTER TABLE SALES DROP SUBPARTITION P4SUB1;
3.截断分区
ALTER TABLE SALES TRUNCATE PARTITION P2;
通过以下代码截断子分区:
ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;
4.合并分区
ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2 UPDATE INDEXES;
--如果省略update indexes子句的话,必须重建受影响的分区的index;
ALTER TABLE range_example MODIFY PARTITION part02 REBUILD UNUSABLE LOCAL INDEXES;
5.拆分分区
ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);
注意:如果是RANGE类型的,使用at,LIST类型的使用values。
6.接合分区(coalesce)
--散列分区表的散列分区接合 ALTER TABLE table_name COALESCE PARTITION; --散列分区表的散列子分区接合 ALTER TABLE table_name MODIFY PARTITION partition_name COALESCE SUBPARTITION;
7.重命名表分区
ALTER TABLE table_name RENAME PARTITION old_name TO new_name; ALTER TABLE table_name RENAME SUBPARTITION old_name TO new_name;
8.交换分区
ALTER TABLE table_name EXCHANGE PARTITION partition_name WITH TABLE nonpartition_name;
9.移动分区
alter table custaddr move partition P_OTHER tablespace system; alter table custaddr move partition P_OTHER tablespace icd_service;
分区移动会自动维护局部分区索引,oracle不会自动维护全局索引,所以需要我们重新rebuild分区索引,具体需要rebuild哪些索引,可以通过dba_part_indexes,dba_ind_partitions去判断。
Select index_name,status From user_indexes Where table_name='CUSTADDR';
10.关于分区表和索引
create index com_index_range_example_id on range_example(id);
2)建立本地分区索引
create index local_index_range_example_id on range_example(id) local;
3)建立全局分区索引
create index gidx_range_example_id on range_example(id) GLOBAL partition by range(id) ( part_01 values less than(1000), part_02 values less than(MAXVALUE) );
对于分区索引的删除,local index 不能指定分区名称,单独的删除分区索引。local index 对应的分区会伴随着data分区的删除而一起被删除。
global partition index 可以指定分区名称,删除某一分区。但是有一点要注意,如果该分区不为空,则会导致更高一级的索引分区被置为UNUSABLE 。
ALTER INDEX gidx_range_exampel_id drop partition part_01 ;
此句将导致part_02 状态为UNUSABLE
1.跨分区查询
select sum( *) from (select count(*) cn from t_table_SS PARTITION (P200709_1) union all select count(*) cn from t_table_SS PARTITION (P200709_2) );
2.查询表上有多少分区
SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='tableName';
3.查询索引信息
select object_name,object_type,tablespace_name,sum(value) from v$segment_statistics where statistic_name IN ('physical reads','physical write','logical reads')and object_type='INDEX' group by object_name,object_type,tablespace_name order by 4 desc --显示数据库所有分区表的信息: select * from DBA_PART_TABLES --显示当前用户可访问的所有分区表信息: select * from ALL_PART_TABLES --显示当前用户所有分区表的信息: select * from USER_PART_TABLES --显示表分区信息 显示数据库所有分区表的详细分区信息: select * from DBA_TAB_PARTITIONS --显示当前用户可访问的所有分区表的详细分区信息: select * from ALL_TAB_PARTITIONS --显示当前用户所有分区表的详细分区信息: select * from USER_TAB_PARTITIONS --显示子分区信息 显示数据库所有组合分区表的子分区信息: select * from DBA_TAB_SUBPARTITIONS --显示当前用户可访问的所有组合分区表的子分区信息: select * from ALL_TAB_SUBPARTITIONS --显示当前用户所有组合分区表的子分区信息: select * from USER_TAB_SUBPARTITIONS --显示分区列 显示数据库所有分区表的分区列信息: select * from DBA_PART_KEY_COLUMNS --显示当前用户可访问的所有分区表的分区列信息: select * from ALL_PART_KEY_COLUMNS --显示当前用户所有分区表的分区列信息: select * from USER_PART_KEY_COLUMNS --显示子分区列 显示数据库所有分区表的子分区列信息: select * from DBA_SUBPART_KEY_COLUMNS --显示当前用户可访问的所有分区表的子分区列信息: select * from ALL_SUBPART_KEY_COLUMNS --显示当前用户所有分区表的子分区列信息: select * from USER_SUBPART_KEY_COLUMNS --怎样查询出oracle数据库中所有的的分区表 select * from user_tables a where a.partitioned='YES' --删除一个表的数据是 truncate table table_name; --删除分区表一个分区的数据是 alter table table_name truncate partition p5;
声明:本文转载自:https://blog.csdn.net/mzglzzc/article/details/46300645