前言:一个好的系统,数据库的设计尤为重要,可以说它影响着程序性能。
(一)表空间及分区概念
表空间:是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间;
分区表:当表中的数据量不断增大,查询数据的速度就会变慢(对表做写操作时表索引需要重新排序),应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个“表空间”(物理文件上),这样查询数据时,不至于每次都扫描整张表而只是从当前的分区查到所要的数据大大提高了数据查询的速度;
(二)什么时候使用分区表
表的大小超过2GB;
表中包含历史数据,新的数据被增加到新的分区中;数据需要某种条件分块维护;
(三)表分区的优缺点
优点:
1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度;
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
4、均衡I/O:可以把不同的分区映射到不同磁盘以平衡I/O,改善整个系统性能;
缺点:
已经存在的表没有方法可以直接转化为分区表。不过 Oracle 提供了在线重定义表的功能。
(四)表分区的几种类型及操作方法
1、Range分区
Range分区是应用范围比较广的表分区方式,它是以列的值的范围来做为分区的划分条件,将记录存放到列值所在的range分区中。如按照时间划分,2015年11月的数据放到p1分区,12月的数据放到p2分区,在创建的时候,需要指定基于的列,以及分区的范围值。在按时间分区时,如果某些记录暂无法预测范围,可以创建maxvalue分区,所有不在指定范围内的记录都会被存储到maxvalue所在分区中;
create table tableTest (id number, times date) partition by range (times)
(
partition p1 values less than (to_date('2015-10-1', 'yyyy-mm-dd')),
partition p2 values less than (to_date('2015-11-1', 'yyyy-mm-dd')),
partition p3 values less than (to_date('2015-12-1', 'yyyy-mm-dd')),
partition p4 values less than (maxvalue)
);
-- 18次插入操作
insert into tableTest(id,times)values(1,sysdate);
commit;
select count(*) from tableTest;
select count(*) from tableTest partition(p3);
1 行已插入。
1 行已插入。
1 行已插入。
已提交。
COUNT(*)
----------
18
COUNT(*)
----------
18
从结果我们不难看出,2015年11月13日我们的数据都根据分区设定的条件放到了p3区。
CREATE TABLE tableTest(TEST_ID NUMBER NOT NULL PRIMARY KEY,STATUS CHAR(1))
PARTITION BY RANGE (tableTest)(
PARTITION PAR1 VALUES LESS THAN (100000) TABLESPACE TABLESPACE1,
PARTITION PAR2 VALUES LESS THAN (200000) TABLESPACE TABLESPACE2
);
这个例子是我们以ID分区,前10万条数据放到第一分区,且第一分区我们存到了TABLESPACE1表空间下,
10万到20万的数据我们放到TABLESPACE2表空间下;
2、Hash分区:
对于那些无法有效划分范围的表,可以使用hash分区,这样对于提高性能还是会有一定的帮助。hash分区会将表中的数据平均分配到你指定的几个分区中,列所在分区是依据分区列的hash值自动分配,因此你并不能控制也不知道哪条记录会被放到哪个分区中,hash分区也可以支持多个依赖列。
create table tableTest(transaction_id number primary key,item_id number(8) not null)
partition by hash(transaction_id)(
partition part_01 tablespace tablespace01,
partition part_02 tablespace tablespace02,
partition part_03 tablespace tablespace03
);
3、List分区:
List分区也需要指定列的值,其分区值必须明确指定,该分区列只能有一个,不能像range或者hash分区那样同时指定多个列做为分区依赖列,但它的单个分区对应值可以是多个。在分区时必须确定分区列可能存在的值,一旦插入的列值不在分区范围内,则插入/更新就会失败,因此通常建议使用list分区时,要创建一个default分区存储那些不在指定范围内的记录,类似range分区中的maxvalue分区。根据某字段,如城市代码分区时,可以指定default,把非分区规则的数据,全部放到这个default分区。
create table custaddr(id varchar2(15 byte) not null,areacode varchar2(4 byte))
partition by list (areacode)(
partition t_list025 values ('025'),
partition t_list372 values ('372') ,
partition t_list510 values ('510'),
partition p_other values (default)
);