1、分区技术使数据库的可管理性变得更加容易,如:用户可以往一个单独的分区中装载数据,而对其他分区没有任何影响;用户可以在单独的分区上创建索引等。
2、分区可以提高表的查询性能,SQL语句的where子句会过滤掉不需要的分区,oracle不会再扫描那些不需要的分区。
3、分区技术减少数据的不可用时间,用户可以单独维护一个分区中的数据,而不影响其他分区中数据的使用。
4、分区技术在数据库级完成,几乎不需要对应用程序做任何修改。
范围分区:根据表中列值的范围将整个表分成不同的部分,如按照时间进行范围分区。
列表分区:使用列表值将表划分成几部分。
哈希分区:使用哈希函数把表分成几部分。
复合分区:同时使用两种分区方法对表进行分区。
范围分区
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);
哈希分区,可以按照分区数量和指定分区两种
如下共有4个分区。
create table people_hash (id number,age number) partition by hash(age) partitions 4;
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);
创建列表分区
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会根据分区信息进行存储。
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.
SQL> alter table people_hash add partition p_hash tablespace hbk_data;
Table altered.
SQL> alter table people_list add partition p_list values ('beijing','shanghai') tablespace users;
Table altered.
截断分区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.
对按照列表进行划分的分区表people_list,对p_merge分区进行拆分
如下是拆分之前的:
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
SQL> alter table people_list drop partition p2_new;
Table altered.
SQL> alter table people_list exchange partition p1 with table t1;
Table altered
SQL> select * from t1;
NAME CITY
-------------------- --------------------
huangbaokang nankang
新建的表t1必须字段名和数据类型跟people_list的一样,这样可实现数据的迁移。