《Oracle从入门到精通》读书笔记第十一章 表分区和索引分区

11.1 分区技术概述
11.2 创建表分区
11.2.1 范围分区
关键字range
当表结构采用范围分区时,首先考虑分区的列应该符合范围分区的方法,其次要考虑列的数据值的取值范围,最后考虑列的边界问题。
SQL> create table ware_retail_part
  2  (
  3  id integer primary key,
  4  retail_date date,
  5  ware_name varchar2(50)
  6  )
  7  partition by range(retail_date)
  8  (
  9  partition par_01 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace TBS_TEST_1,
 10  partition par_02 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace TBS_TEST_2,
 11  partition par_03 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace TBS_TEST_3,
 12  partition par_04 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace TBS_TEST_4
 13  );

Table created

create table ware_retail_part
(
id integer primary key,
retail_date date,
ware_name varchar2(50)
)
partition by range(retail_date)
(
partition par_01 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace TBS_TEST_1,
partition par_02 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace TBS_TEST_2,
partition par_03 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace TBS_TEST_3,
partition par_04 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace TBS_TEST_4
);

insert into ware_retail_part
values(1,to_date('2011-01-20','yyyy-mm-dd'),'ipad');

insert into ware_retail_part
values(2,to_date('2011-04-15','yyyy-mm-dd'),'iphone');

insert into ware_retail_part
values(3,to_date('2011-07-25','yyyy-mm-dd'),'ipod');

通过分区表查询数据:
SQL> select * from ware_retail_part partition(par_02);

                                     ID RETAIL_DATE WARE_NAME
--------------------------------------- ----------- --------------------------------------------------
                                      2 2011-4-15   iphone

range分区的字段可以是两个或者多个

create table ware_retail_part2
(
id integer primary key,
retail_date date,
ware_name varchar2(50)
)
partition by range(id,retail_date)
(
partition par_01 values less than(10000,to_date('2011-12-01','yyyy-mm-dd')) tablespace TBS_TEST_1,
partition par_02 values less than(20000,to_date('2012-12-01','yyyy-mm-dd')) tablespace TBS_TEST_2,
partition par_03 values less than(maxvalue,maxvalue) tablespace TBS_TEST_3,
);

11.2.2 散列分区(HASH分区)
create table ware_retail_part3
(
id integer primary key,
retail_date date,
ware_name varchar2(50)
)
partition by hash(id)
(
partition par_01 tablespace TBS_TEST_1,
partition par_02 tablespace TBS_TEST_2
);

SQL> insert into ware_retail_part3
  2  values(99,to_date('2011-11-11','yyyy-mm-dd'),'mac');

1 row inserted

SQL> select * from ware_retail_part3;

                                     ID RETAIL_DATE WARE_NAME
--------------------------------------- ----------- --------------------------------------------------
                                     99 2011-11-11  mac


SQL> select * from ware_retail_part3 partition(par_01);

                                     ID RETAIL_DATE WARE_NAME
--------------------------------------- ----------- --------------------------------------------------

SQL> select * from ware_retail_part3 partition(par_02);

                                     ID RETAIL_DATE WARE_NAME
--------------------------------------- ----------- --------------------------------------------------
                                     99 2011-11-11  mac

由系统自动分配分区名:
create table ware_retail_part4
(
id integer primary key,
retail_date date,
ware_name varchar2(50)
)
partition by hash(id)
partitions 2
store in(TBS_TEST_1,TBS_TEST_2);

指定所有分区的初始分配空间
create table ware_retail_part5
(
id integer primary key,
retail_date date,
ware_name varchar2(50)
)
storage(initial 2048k)
partition by hash(id)
(
partition par_01 tablespace TBS_TEST_1,
partition par_02 tablespace TBS_TEST_2
);

11.2.3 列表分区
如果表的某个列的值可以枚举,则可以考虑对表进行列表分区
create table clients
(
id integer primary key,
name varchar2(50),
province varchar2(50)
)
partition by list(province)
(
partition shangdong values('山东'),
partition guangdong values('广东'),
partition yunan values('云南')
);

SQL> insert into clients
  2  values(19,'stone','云南');

1 row inserted

SQL> col id for a10;
SQL> col name for a10;
SQL> col province for a10;
SQL> select * from clients partition(yunan);

        ID NAME       PROVINCE
---------- ---------- ----------
        19 stone      云南

11.2.4 组合分区
oracle支持以下组合分区方案
a、范围-范围分区
b、范围-散列分区
c、范围-列表分区
d、列表-列表分区
e、列表-范围分区
f、列表-散列分区
create table person2
(
id number primary key,
name varchar2(50),
sex varchar2(2)
)
partition by range(id)
subpartition by hash(name)
subpartitions 2 store in(TBS_TEST_1,TBS_TEST_2)
(
partition par1 values less than(5000),
partition par2 values less than(10000),
partition par3 values less than(maxvalue)
);

11.2.5 Interval分区
范围分区的一种增强功能,只有最开始的分区是永久分区,随着数据的增多会分配更多的部分,并自动创建新的分区和本地索引。
create table salerecord
(
id number primary key,
goodsname varchar2(50),
saledate date,
quantity number
)
partition by range(saledate)
interval(numtoyminterval(1,'year'))
(
partition par_first values less than(to_date('2012-01-01','yyyy-mm-dd'))
);

对于已经进行了范围分区的表,可以通过使用alter table命令的set interval选项扩展成为interval分区。

11.3 表分区策略
1、识别大表(analyze table)
2、大表如何分区,一般按时间分区
3、分区的表空间规划

11.4 管理表分区
11.4.1 添加表分区
alter table clients
add partition hebei values('河北')
storage(initial 10k next 20k) tablespace TBS_TEST_1
nologging;

11.4.2 合并分区
1、合并散列分区
alter table ... coalesce partition
SQL> alter table ware_retail_part4 coalesce partition;

Table altered

2、合并复合分区
alter table ... modify
SQL> alter table person2 modify partition par3 coalesce subpartition;

Table altered

11.4.3 删除分区
可以从范围分区或复合分区中删除分区,但是散列分区和复合分区的散列子分区,只能通过合并来达到删除的目的
1、删除一个表分区
删除分区时,该分区的数据也被删除,如果不希望删除数据,则必须采用合并分区的方法。
alter table ... drop partition
SQL> alter table ware_retail_part drop partition par_04;

Table altered

2、删除有数据和全局索引的表分区
如果分区表中包含了数据,并且在表中定义了一个或者多个全局索引,可以使用alter table ... drop partition语句删除表分区,这样可以保留全局索引,但是索引会被标识为不可用(unusable),因而需要重建索引。
SQL> alter table ware_retail_part drop partition par_03;

Table altered

3、使用delete和alter table ... drop partition语句
先执行delete语句删除分区的所有数据行
delete from ware_retail_part where retail_date >= to_date('2011-07-01','yyyy-mm-dd');

SQL> alter table ware_retail_part drop partition par_02;

Table altered

4、删除具有完整性约束的分区
两种方法:
(1)首先禁止完整性约束,然后执行alter table ... drop partition,最后激活约束
alter table books_1 disable constraints book_pk;
alter table books_1 drop partition part_01;
alter table books_1 enable constraints book_pk;
(2)首先执行delete语句删除分区中的行,然后用alter table ... drop partition语句删除分区
delete from books_1 where bookno<1000;
alter table books_1 drop partition part_01;

11.4.4 并入分区
使用merge partition语句,不能对hash分区执行merge partition语句
(1)创建销售记录表并分区
create table sales
(
id number primary key,
goodsname varchar2(10),
saledate date
)
partition by range(saledate)
(
partition part_sea1 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace TBS_TEST_1,
partition part_sea2 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace TBS_TEST_2,
partition part_sea3 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace TBS_TEST_3,
partition part_sea4 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace TBS_TEST_4
);
(2)创建局部索引
create index index_3_4 on sales(saledate)
local
(
partition part_sea1 tablespace TBS_TEST_1,
partition part_sea2 tablespace TBS_TEST_2,
partition part_sea3 tablespace TBS_TEST_3,
partition part_sea4 tablespace TBS_TEST_4
);
(3)使用alter table ... merge partition把第三个分区并入到第四个分区
alter table sales merge partitions part_sea3,part_sea4 into partition part_sea4;
SQL> 

Table altered
(4)重新建立局部索引
SQL> alter table sales modify partition part_sea4 rebuild unusable local indexes;

Table altered

11.5 创建索引分区
一般来说,如果索引对应的表数据量非常大,比如几百万甚至上千万条数据,建议对索引进行分区。
11.5.1 索引分区概述
11.5.2 本地索引分区
本地索引分区就是使用和分区表同样的分区键进行分区的索引,也就是说,索引分区所采用的列与该表的分区所采用的列是相同的
(1)准备好所需要的表空间
create tablespace ts_1 datafile '/ora/app/oracle/oradata/stone1/ts1.dbf'
size 10m
extent management local autoallocate;
create tablespace ts_2 datafile '/ora/app/oracle/oradata/stone1/ts2.dbf'
size 10m
extent management local autoallocate;
create tablespace ts_3 datafile '/ora/app/oracle/oradata/stone1/ts3.dbf'
size 10m
extent management local autoallocate;
(2)创建分区表
create table studentgrade
(
id number primary key,
name varchar2(10),
subject varchar2(10),
grade number
)
partition by range(grade)
(
partition par_nopass values less than(60) tablespace ts_1,
partition par_pass values less than (80) tablespace ts_2,
partition par_good values less than(maxvalue) tablespace ts_3
); 
(3)创建本地索引分区
create index grade_index on studentgrade(grade)
local
(
partition p1 tablespace ts_1,
partition p2 tablespace ts_2,
partition p3 tablespace ts_3
);
(4)查看索引分区信息
SQL> select partition_name,tablespace_name from dba_ind_partitions where index_name='GRADE_INDEX';

PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------
P1                             TS_1
P2                             TS_2
P3                             TS_3

11.5.3 全局索引分区
全局索引就是没有与分区表有相同分区键的分区索引。当分区中出现许多事务并且要保证所有分区中的数据记录唯一时,采用全局索引分区
无论表是否采用分区,都可以对表采用全局索引分区。此外,不能对cluster表,位图索引采用全局索引分区。
create table books
(
isbn varchar2(50) primary key,
name varchar2(50),
author varchar2(50),
version integer,
pbdate date,
saleprice number
);

create index index_saleprice on books(saleprice)
global partition by range(saleprice)
(
partition p1 values less than(30),
partition p2 values less than(50),
partition p3 values less than(maxvalue)
);

SQL> create index index_isbn on books(isbn)
global partition by hash(isbn);

ORA-01408: 此列列表已索引

SQL> select index_name from dba_indexes where table_name='BOOKS';

INDEX_NAME
------------------------------
SYS_C0011235
INDEX_SALEPRICE

SQL> drop index sys_c0011235;

drop index sys_c0011235

ORA-02429: 无法删除用于强制唯一/主键的索引

SQL> select table_name,constraint_name from user_constraints where table_name='BOOKS';

TABLE_NAME                     CONSTRAINT_NAME
------------------------------ ------------------------------
BOOKS                          SYS_C0011235

SQL> alter table books disable constraint sys_c0011235;

Table altered

SQL> create index index_isbn on books(isbn)
  2  global partition by hash(isbn);

Index created

11.6 管理索引分区
11.6.1 索引分区管理的操作列表
对索引分区进行维护的alter index子句
维护分类 索引类型 范围分区 hash或list分区 组合分区
删除索引分区 全局 drop partition
局部 无效
重建索引分区 全局 rebuild partition
局部 rebuild partition rebuild subpartition
更名索引分区 全局 rename partition
局部 rename partition rename subpartition
分割索引分区 全局 split partition
局部 无效
11.6.2 索引分区管理的实际操作
1、删除索引分区
SQL> alter index index_saleprice drop partition p2;
Index altered

SQL> alter index index_saleprice drop partition p1;
Index altered

对于全局索引分区,不能删除索引的最高分区,否则系统会提示错误
在删除若干索引分区后,如果只剩一个索引分区,则需要对这个分区进行重建

SQL> alter index index_saleprice rebuild partition p3;
Index altered

2、重命名索引分区
语法格式:
alter index index_name
rename partition partition_old_name to partition_new_name

SQL> alter index index_saleprice rename partition p3 to p_new;
Index altered

你可能感兴趣的:(oracle,表分区,索引分区)