oracle分区详解

分区技术有如下优点:

1、分区技术使数据库的可管理性变得更加容易,如:用户可以往一个单独的分区中装载数据,而对其他分区没有任何影响;用户可以在单独的分区上创建索引等。

2、分区可以提高表的查询性能,SQL语句的where子句会过滤掉不需要的分区,oracle不会再扫描那些不需要的分区。

3、分区技术减少数据的不可用时间,用户可以单独维护一个分区中的数据,而不影响其他分区中数据的使用。

4、分区技术在数据库级完成,几乎不需要对应用程序做任何修改。

Oracle提供的分区方法

范围分区:根据表中列值的范围将整个表分成不同的部分,如按照时间进行范围分区。
列表分区:使用列表值将表划分成几部分。
哈希分区:使用哈希函数把表分成几部分。
复合分区:同时使用两种分区方法对表进行分区。

分区表的创建

范围分区

create table people(
  id number,
  age int not null,
  address varchar2(100))
  partition by range (age)
  (partition p1 values less than (10) tablespace users,
  partition p2 values less than (20) tablespace hbk_data,
  partition p3 values less than (30) tablespace users);

在客户端的显示如下:oracle分区详解_第1张图片

哈希分区,可以按照分区数量和指定分区两种
如下共有4个分区。

create table people_hash (id number,age number) partition by hash(age) partitions 4;

系统生成分区名
oracle分区详解_第2张图片
也可以指定分区,名字和存储表空间信息

create table people_hash2(id number,age number)  partition by hash(age) (partition pt1 tablespace users,partition pt2 tablespace hbk_data,partition pt3 tablespace users);

如下:生成了自定义分区名
oracle分区详解_第3张图片

创建列表分区

create table people_list (name varchar2(20),city varchar2(20)) partition by list (city)  (partition p1 values ('ganzhou','nankang') tablespace users,partition p2 values ('quannan','dingnan')  tablespace hbk_data);

oracle分区详解_第4张图片

分区表插入数据

分区表的数据插入跟普通表的插入方式差不多,oracle会根据分区信息进行存储。

SQL> insert into people_list(name,city) values ('huangbaokang','nankang');

1 row created.
SQL> commit;

Commit complete.

查询指定分区的数据

可以知道city为nankang的存储分区为p1,查询如下:

SQL> select * from people_list;

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> select * from people_list partition(p2);

no rows selected

分区表中的更新

本人huangbaokang(黄宝康),南康人(nankang)存储分区为p1,假设分区p2中全南也有一个叫huangbaokang的人,我们需要修改存储分区p2的city为赣州(ganzhou)人。注意:这个修改会改变原来在p2的分区数据转到p1分区


SQL> insert into people_list (name,city) values ('huangbaokang','quannan');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> select * from people_list partition(p2);

NAME		     CITY
-------------------- --------------------
huangbaokang	     quannan

SQL> update people_list partition(p2) set city='ganzhou' where name='huangbaokang';
update people_list partition(p2) set city='ganzhou' where name='huangbaokang'
       *
ERROR at line 1:
ORA-14402: updating partition key column would cause a partition change

可以看到,当更新分区表的分区键时,会出现ORA-14402错误
解决方法为对表启用行移动

SQL> alter table people_list enable row movement;

Table altered.

SQL> update people_list partition(p2) set city='ganzhou' where name='huangbaokang';

1 row updated.

SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang
huangbaokang	     ganzhou

SQL> select * from people_list partition(p2);

no rows selected

表分区的删除

SQL> delete from people_list partition(p1) where city='ganzhou';

1 row deleted.

SQL> commit;

Commit complete.

SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

添加分区

SQL> alter table people add partition padd values less than (90) tablespace users;

Table altered.

oracle分区详解_第5张图片

SQL> alter table people_hash add partition p_hash tablespace hbk_data;

Table altered.

oracle分区详解_第6张图片

SQL> alter table people_list add partition p_list values ('beijing','shanghai') tablespace users;

Table altered.

oracle分区详解_第7张图片

截断分区(truncate)

截断分区p1中的数据(会释放空间)

SQL> select * from people_list partition(p1);      

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> alter table people_list truncate partition p1;

Table truncated.

SQL> select * from people_list partition (p1);

no rows selected

如下方式不会释放空间

delete from people_list partition(p1);

合并分区

由于上面删除了数据,为了演示合并分区,我们添加模拟数据

SQL> insert into people_list(name,city) values ('huangbaokang','nankang');

1 row created.

SQL> insert into people_list(name,city) values('zhanglulu','quannan');

1 row created.
SQL> commit;

Commit complete.
SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> select * from people_list partition(p2);

NAME		     CITY
-------------------- --------------------
zhanglulu	     quannan
SQL> alter table people_list merge partitions p1,p2 into partition p_merge;

Table altered.
SQL> select * from people_list partition(p_merge);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang
zhanglulu	     quannan

SQL> select * from people_list partition(p1);
select * from people_list partition(p1)
                                    *
ERROR at line 1:
ORA-02149: Specified partition does not exist


SQL> select * from people_list partition(p2);
select * from people_list partition(p2)
                                    *
ERROR at line 1:
ORA-02149: Specified partition does not exist

可以发现,p1和p2分区的数据全部存储在了分区p_merge,合并分区之后,原来的分区将不存在。
注意点:不能合并安装Hash进行划分的两个分区

拆分分区

拆分分区跟合并分区相反,即把一个分区分成多个分区。
对范围分区进行拆分


SQL> alter table people split partition p2 at (15) into (partition p2_begin,partition p2_end);

Table altered.

oracle分区详解_第8张图片
可以看到生成的SQL建表语句也发生了变化。
oracle分区详解_第9张图片

对按照列表进行划分的分区表people_list,对p_merge分区进行拆分
如下是拆分之前的:
oracle分区详解_第10张图片


SQL> alter table people_list split partition p_merge values ('ganzhou','nankang') into (partition p1,partition p2);

Table altered.

SQL> select * from people_list partition(p1);

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

SQL> select * from people_list partition(p2);

NAME		     CITY
-------------------- --------------------
zhanglulu	     quannan
SQL> select * from people_list partition(p_merge);
select * from people_list partition(p_merge)
                                    *
ERROR at line 1:
ORA-02149: Specified partition does not exist

可知ganzhou,nankang拆分到p1,其他的拆分到p2,并且原有分区将不存在。注意,不能拆分按照Hash进行划分的两个分区。

重命名分区

SQL> alter table people_list rename partition p2 to p2_new;

Table altered.

可知,从拆分出来的p1和p2,现在经过重命名成了p2_new
oracle分区详解_第11张图片

删除分区

SQL> alter table people_list drop partition p2_new;

Table altered.

可见,p2_new分区被删除了
oracle分区详解_第12张图片

交换分区

SQL>  alter table people_list exchange partition p1 with table t1;

Table altered
SQL> select * from t1;

NAME		     CITY
-------------------- --------------------
huangbaokang	     nankang

新建的表t1必须字段名和数据类型跟people_list的一样,这样可实现数据的迁移。

你可能感兴趣的:(oracle)