通过PL/SQL developer工具查看表空间的情况
创建两个表空间,参考《Oracle创建表空间和表》
SQL> create TABLESPACE TBSP_1 DATAFILE 'D:\app\Administrator\oradata\oracle\TBSP_1.dbf' SIZE 10M;
表空间已创建。
SQL> CREATE TABLESPACE TBSP_2 DATAFILE 'D:\app\Administrator\oradata\oracle\TBSP_2.dbf' SIZE 10M;
表空间已创建。
查看创建好的表空间
SQL> select * from v$tablespace;
TS# NAME INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
0 SYSTEM YES NO YES
1 SYSAUX YES NO YES
2 UNDOTBS1 YES NO YES
4 USERS YES NO YES
3 TEMP NO NO YES
6 TBSP_1 YES NO YES
7 TBSP_2 YES NO YES
分区
- 减少维护工作量
- 增强数据库可用性
- 均衡I/O
- 分区对用户透明,对其存在无感知
- 提高查询速度
1 范围分区(range)
- 数据根据分区键的范围进行分布
例如:日期分区键–“08-2019”就会包括从“01-08-2019”到“31-08-2019”之间的所有分区键值。
实例:
创建一个商品零售表,根据销售日期创建四个范围分区。
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 TBSP_1,
partition par_02 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace TBSP_1,
partition par_03 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace TBSP_2,
partition par_04 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace TBSP_2
)
创建好后,插入若干条记录:
SQL> insert into ware_retail_part values(1,to_date('2011-01-20','yyyy-mm-dd'),'平板电 脑');
SQL> insert into ware_retail_part values(2,to_date('2011-04-15','yyyy-mm-dd'),'智能手 机');
SQL> insert into ware_retail_part values(3,to_date('2011-07-25','yyyy-mm-dd'),'MP5');
查看分区和表格:
SQL> select * from ware_retail_part partition(par_02);
ID RETAIL_DATE WARE_NAME
---------- -------------- --------------------------------------------------
2 15-4月 -11 智能手 机
SQL> select * from ware_retail_part;
ID RETAIL_DATE WARE_NAME
---------- -------------- --------------------------------------------------
1 20-1月 -11 平板电 脑
2 15-4月 -11 智能手 机
3 25-7月 -11 MP5
如果是多范围分区,比如根据销售编号和销售日期的组合创建三个分区:
参考《oracle 创建分区表以及自动添加分区》
SQL> create table ware_retail_part2(
2 id integer primary key,
3 retail_no integer,
4 retail_date date,
5 ware_name varchar2(50)
6 )
7 partition by range(retail_date,retail_no)
8 (
9 partition par_01 values less than(to_date('2011-04-01','yyyy-mm-dd'),5) tablespace TBSP_1,
10 partition par_02 values less than(to_date('2011-08-01','yyyy-mm-dd'),10) tablespace TBSP_1,
11 partition par_03 values less than(to_date('2011-12-01','yyyy-mm-dd'),15) tablespace TBSP_2
12 )
13 /
SQL> insert into ware_retail_part2 values(2,12,to_date('2011-10-25','yyyy-mm-dd'),'MP5');
SQL> select * from ware_retail_part2 partition(par_03);
ID RETAIL_NO RETAIL_DATE WARE_NAME
---------- ---------- -------------- ----------------------
2 12 25-10月-11 MP5
2 HASH列分区
即散列分区,列值无法确定时采用。
实例:
创建一个person表,为该表创建hash分区(分区列为id)
SQL> create table person
2 (
3 id number,
4 personname varchar2(50)
5 )
6 storage(initial 2084k)
7 partition by hash(id)
8 (
9 partition part1 tablespace tbsp_1,
10 partition part2 tablespace tbsp_2
11 );
表已创建。
SQL> insert into person values(55,'wj');
已创建 1 行。
SQL> select * from person partition(part1);
ID PERSONNAME
---------- --------------------------------------------------
55 wj
3 列表分区
创建一个用于保存客户信息的clients,然后以PROVINCE列为分区键创建列分区;
SQL> l
1 create table clients
2 (
3 id integer primary key,
4 name varchar2(50),
5 province varchar2(20)
6 )
7 partition by list(province)
8 (
9 partition shandong values('山东省'),
10 partition guangdong values('广东省'),
11 partition yunnan values('云南省')
12* )
SQL> /
表已创建。
SQL> insert into clients values (19,'东方','云南省');
已创建 1 行。
SQL> select * from clients partition(yunnan);
ID NAME PROVINCE
---------- -------------------------------------------------- --------------------
19 东方 云南省
列表分区这里有一个小测试可以自我简单测试下:链接🔗
分区表添加子分区
参考《对分区表添加子分区》
创建一个保存人员信息的数据表PERSON2,然后建立三个范围分区,每个分区包含两个子分区,子分区没有名字,有系统自动生成,并要求其分布在2个制定的表空间中。
create table persons2(
id integer primary key,
personname varchar2(50)
)
partition by range(id)
subpartition by hash(personname)
SUBPARTITIONS 2
(
partition part_1 values less than(5) tablespace tbsp_1,
partition part_2 values less than(10) tablespace tbsp_1,
partition part_3 values less than(15) tablespace tbsp_2
);
4 interval分区
创建的分区作为元数据,只有最开始的分区是永久分区,随着数据增加会分配更多,并自动创建新的分区和本地索引。
实例:
创建一个表saleRecord,然后为该表创建一个Interval分区
SQL> create table saleRecord
2 (
3 id number primary key,
4 goodsname varchar2(50),
5 saledate date,
6 quantity number
7 )
8 partition by range(saledate)
9 interval (numtoyminterval(1,'year'))
10 (
11 partition par_first values less than (to_date('2020-01-01','yyyy-mm-dd'))
12 );
表已创建。
SQL> insert into saleRecord values(1,'MP5',sysdate,123);
SQL> select TABLE_NAME, PARTITION_NAME from user_tab_partitions where table_name='SALERECORD';
#查看表中包含的分区
TABLE_NAME PARTITION_NAME
----------- ------------------------------
SALERECORD PAR_FIRST
SALERECORD SYS_P47
SQL> select * from saleRecord partition(par_first);
未选定行
SQL> select * from saleRecord partition(SYS_P47);
ID GOODSNAME SALEDATE QUANTITY
---------- -------------------------------------------------- -------------- ----------
1 MP5 02-4月 -20 123
5 添加分区
实例:
为cilents添加一个省分为“河北省”的表分区
SQL> alter table clients
2 add partition hebei values('河北省')
3 storage(initial 10K next 20k)tablespace tbsp_1
4 nologging;
表已更改。
SQL> select partition_name from user_tab_partitions where table_name ='CLIENTS';
PARTITION_NAME
------------------------------
SHANDONG
GUANGDONG
YUNNAN
HEBEI
6 并入表分区
- MERGE PARTITION语句,将相邻的范围分区合并在一起,变成新的分区;
- 合并分区为空,则标识为UNSABLE;
- 不能对HASH分区表执行MERGE PARTITION语句;
- 并入范围分区是将两个以上的分区合并到一个存在的分区中,合并后索引需重建
实例:
创建一个销售记录表sales,然后岁该表的记录按照销售日期分为四个分区;再建立局部索引
SQL> create table sales
2 (
3 id number primary key,
4 goodsname varchar2(10),
5 saledate date
6 )
7 partition by range(saledate)
8 (
9 partition part_seal values less than (to_date('2011-04-01','yyyy-mm-dd')) tablespace tbsp_1,
10 partition part_sea2 values less than (to_date('2011-07-01','yyyy-mm-dd')) tablespace tbsp_2,
11 partition part_sea3 values less than (to_date('2011-10-01','yyyy-mm-dd')) tablespace tbsp_1,
12 partition part_sea4 values less than (to_date('2012-01-01','yyyy-mm-dd')) tablespace tbsp_2
13 )
14 /
表已创建。
SQL> create index index_3_4 on sales(saledate)
2 local
3 (
4 partition part_sea1 tablespace tbsp_1,
5 partition part_sea2 tablespace tbsp_2,
6 partition part_sea3 tablespace tbsp_1,
7 partition part_sea4 tablespace tbsp_2
8 );
索引已创建。
将第三个分区并入到第四个分区中,并重建局部索引:
# 这里的merge partitions记得加s
SQL> alter table sales merge partitions part_sea3,part_sea4 into partition part_sea4;
表已更改。
SQL> alter table sales modify partition part_sea4 rebuild unusable local indexes;
表已更改。
SQL> select partition_name from user_tab_partitions where table_name ='SALES';
PARTITION_NAME
------------------------------
PART_SEAL
PART_SEA2
PART_SEA4
如果是将第二个和第三个分区并入到第四个分区中,可以合并两次:
SQL> alter table sales2 merge partitions part_sea2,part_sea3 into partition part_sea3;
表已更改。
SQL> alter table sales2 merge partitions part_sea3,part_sea4 into partition part_sea4;
表已更改。
SQL> select partition_name from user_tab_partitions where table_name ='SALES2';
PARTITION_NAME
------------------------------
PART_SEAL
PART_SEA4
7 创建本地索引分区
本地索引分区与该表分区所采用的列是相同的。
1 准备表空间:
SQL> create TABLESPACE ts_1 DATAFILE 'D:\app\Administrator\oradata\oracle\ts_1.dbf' SIZE 10M extent management local autoallocate;
表空间已创建。
SQL> create TABLESPACE ts_2 DATAFILE 'D:\app\Administrator\oradata\oracle\ts_2.dbf' SIZE 10M extent management local autoallocate;
表空间已创建。
SQL> create TABLESPACE ts_3 DATAFILE 'D:\app\Administrator\oradata\oracle\ts_3.dbf' SIZE 10M extent management local autoallocate;
表空间已创建。
2 创建一个存储学生成绩的分区表studentgrade,该表有三个分区,分别位于三个不同表空间:
SQL> create table studentgrade
2 (
3 id number primary key,
4 name varchar2(10),
5 subject varchar2(10),
6 grade number
7 )
8 partition by range(grade)
9 (
#小于60分,不及格
10 partition par_nopass values less than(60) tablespace ts_1,
#小于70分,及格
11 partition par_pass values less than(70) tablespace ts_2,
#大于等于70分,优秀
12 partition par_good values less than(maxvalue) tablespace ts_3
13 );
表已创建。
3 根据表分区创建本地索引分区
SQL> create index grade_index on studentgrade(grade)
2 local
3 (
4 partition p1 tablespace ts_1,
5 partition p2 tablespace ts_2,
6 partition p3 tablespace ts_3
7 );
索引已创建。
4 根据dba_ind_partitions查看索引分区信息
SQL> select partition_name,tablespace_name from dba_ind_partitions where index_name ='GRADE_INDEX';
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
P3 TS_3
P2 TS_2
P1 TS_1
8 索引分区维护
SQL> create table books2(
2 BooksNo number(4) not null,
3 BookName varchar2(20),
4 Author varchar2(10),
5 SalePrice number(9,2),
6 PublisherNo varchar2(4) not null,
7 PublisherDate date,
8 ISBN varchar2(20) not null
9 );
表已创建。
SQL>
SQL> create index index_salesprice on Books2(SalePrice)
2 global partition by range(SalePrice)
3 (
4 partition p1 values less than (30),
5 partition p2 values less than (50),
6 partition p3 values less than (maxvalue)
7 );
索引已创建。
SQL> alter index index_salesprice drop partition p2;
索引已更改。
SQL> alter index index_salesprice drop partition p1;
索引已更改。
全局索引分区,不能删除索引的最高分区,否则系统报错
SQL> alter index index_salesprice drop partition p3;
alter index index_salesprice drop partition p3
*
第 1 行出现错误:
ORA-14078: 您不能删除 GLOBAL 索引的最高分区
9 索引分区重命名
alter index index_name rename partition partition_old_name to parttion_new_name;