标签:
转载请注明出处:http://blog.csdn.net/anxpp/article/details/51869335,谢谢!
下例中的表设计并不一定,仅作演示使用。
1、概述
即使业务拆分,有时还是不能避免某张表的数据(行数)过多。
当单表数据过多时,会影响整体的性能,查询将变得更慢,数据的备份恢复也会花费更多时间。
However,数据库一般都提供了一个将单表拆分成多张表的机制,以更容易的管理表和解决性能问题。这种方式(把表的行分为多个部分)划分表数据的方法就是对表的分区。被分区的表是分区表,拆分后的每一部分叫一个分区。
分区是解决大型表问题的有效方法:
- 改善表的查询性能。
- 表更容易管理。
- 导入导出会更好的执行。
2、分区表的创建
有多种方式创建分区表。
2.1、范围分区
按值的范围对表进行分区,就是范围分区。
创建范围分区的分区表命令为:PARTITION BY RANGE。
下面看一个示例:
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by range(rating)
- (
- partition book_low values less than (‘3‘),
- partition book_normal values less than (‘5‘),
- partition book_great values less than (maxvalue)
- );
此例,我们创建了一张book表,我们根据他的评分分别存入不同分区中。
下面我们插入一下数据,并看看分区表中的数据记录:
- insert into book values(‘c++‘,‘test‘,‘5‘);
- insert into book values(‘java‘,‘test‘,‘5‘);
- insert into book values(‘c#‘,‘test‘,‘3‘);
- insert into book values(‘c‘,‘test‘,‘4‘);
- insert into book values(‘数学‘,‘test‘,‘1‘);
- insert into book values(‘语文‘,‘test‘,‘2‘);
- insert into book values(‘化学‘,‘test‘,‘2‘);
- analyze table BOOK compute statistics;
- select t.PARTITION_NAME,t.num_rows from all_tab_partitions t where t.table_name = ‘BOOK‘;
上面的analyze语句用于分析这张表,这样才能得到准确的分区表信息。
结果:
- BOOK_NORMAL 2
- BOOK_LOW 3
- BOOK_GREAT 2
确实是按我们希望的那样分区保存的。
下面的其他分区方式,查看各个分区的数据记录条数都是用同样的方法。
2.2、散列分区
除了范围分区,Oracle也支持散列分区,这个概念大家应该比较清楚。
此时的分区语句为:PARTITION BY HASH。
同时我们要设置要分区的个数,考虑到Oracle中的分区映射实现方式(本人暂时也不清楚具体的实现方式),建议分区的个数设置为2的乘方,以便使数据均匀分布。
示例:
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by hash(title)
- partitions 16;
可以指定分区的表空间:
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by hash(title)
- partitions 2
- store in (book_ts1,book_ts2);
我们也可以指定每个分区的名字:
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by hash(title)
- (
- partition book_part1,
- partition book_part2
- );
或者同时指定分区名和表空间:
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by hash(title)
- (
- partition book_part1 tablespace part1_ts,
- partition book_part2 tablespace part2_ts
- );
这样可以为分区和指定更有意义的名字。
2.3、列表分区
列表分区也是一种可行的分区方法,可代替范围分区和散列分区。
在列表分区中,我们需要告诉Oracle所有可能的值,并指定应该插入相应行的分区。
示例:
- --列表分区
- drop table book;
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1)
- )
- partition by list(rating)
- (
- partition book_part1 values(‘5‘),
- partition book_part2 values(‘4‘,‘3‘),
- partition book_part3 values(default)
- );
其中,default关键字用于处理没有在列表中列出的值,他们讲保存到这个分区。
2.4、间隔分区
间隔分区是从Oracle 11g开始新增的一种新的分区类型,但实际上它是范围分区的一种,不过是添加了特性。
间隔分区中不需要指定间隔持续时间,而是指定每个分区的时长。
当插入新行时,将根据间隔定义确定将此行插入到那个分区,如果没有对应分区,将自动创建(所以插入数据前最好检查数据值约束,以免创建不必要的分区,如年份错误输入为2076)。
示例:
- --间隔分区
- drop table book;
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1),
- publishAt date
- )
- partition by range(publishAt)
- interval (numtoyminterval(1,‘year‘))
- (
- partition p2010 values less than (to_date(‘2011-01-01‘,‘yyyy-mm-dd‘))
- );
- insert into book values(‘c++‘,‘test‘,‘5‘,to_date(‘2015-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘java‘,‘test‘,‘5‘,to_date(‘2011-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘c#‘,‘test‘,‘3‘,to_date(‘2014-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘c‘,‘test‘,‘4‘,to_date(‘2016-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘数学‘,‘test‘,‘1‘,to_date(‘2012-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘语文‘,‘test‘,‘2‘,to_date(‘2015-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘化学‘,‘test‘,‘2‘,to_date(‘2014-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘政治‘,‘test‘,‘2‘,to_date(‘2002-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘自然‘,‘test‘,‘2‘,to_date(‘2003-03-15‘,‘yyyy-mm-dd‘));
- insert into book values(‘生物‘,‘test‘,‘2‘,to_date(‘2006-03-15‘,‘yyyy-mm-dd‘));
这里会按年份将不同时间出版的放入不同的分区表,其中所有2011年前的统一方法p2010分区中。
查看状态:
- SYS_P681 1
- SYS_P680 1
- SYS_P679 2
- SYS_P678 1
- SYS_P677 2
- P2010 3
可以看到,很多分区都是自动创建的。
2.5、引用分区
引用分区也是从Oracle 11g开始支持的。
如果一个分区表依赖与另一个分区表,就可以使用引用分区,这时两张表将同步分区。
使用的语句是:partition by reference
示例:
- create table orders(
- order_id number primary key,
- order_date TIMESTAMP
- )
- PARTITION BY RANGE(order_date)
- interval (numtoyminterval(1,‘month‘))
- (
- partition p2010 values less than (to_date(‘2011-01-01‘,‘yyyy-mm-dd‘))
- );
- CREATE TABLE order_items
- (
- order_id NUMBER NOT NULL,
- item_id NUMBER(3) primary key,
- CONSTRAINT order_items_fk
- FOREIGN KEY(order_id) REFERENCES orders(order_id)
- )
- PARTITION BY REFERENCE(order_items_fk);
orders表按月分区,order_items将同步orders表的分区。
2.6、索引分区
索引也可以按照与对表进行分区时所用的相同范围的值来分区。
使用方式为:
- create index index_name
- on table_name(column_name)
- local
- (
- --分区...
- );
使用local关键字时,如上不需要指定范围,范围将由表的分区策略决定,所以索引分区与表分区是一一对应的,对于分区来说是本地的。
如果使用global关键字,就可以创建于表分区范围不同的所以分区。
局部(local)索引易于管理,但是全局所以进行唯一性检查的速度可能会更快。
2.7、创建子分区
子分区即分区的分区。
可以使用子分区将各种方式的分区结合起来使用。对于非常非常大的表来说,这种组合分区是一种吧数据分成可管理和可调整的组成部分的有效方法。
示例:
- drop table book;
- create table book(
- title nvarchar2(50) primary key,
- publisher nvarchar2(20),
- rating nvarchar2(1),
- publishAt date
- )
- partition by range(rating)
- subpartition by hash(title)
- subpartitions 8
- (
- partition book_low values less than (‘3‘),
- partition book_normal values less than (‘5‘),
- partition book_great values less than (maxvalue)
- );
此处先根据评分分区,再通过title进行hash分区。
3、管理分区表
对于分区表的管理,依然是使用ALTER TABLE命令。
相关的操作有:ADD、DROP、EXCHANGE、MOVE、MODIFY、RENAME、SPLIT、TRUNCATE等。
分区表中的数据是由Oracle内部实现分离和管理的,对于分区表,我们的操作就像是普通表一样的。
分区表的一种常见用法是可以使应用程序的停机时间最小化。
另一个优点是可以对不同的分区采用不同的压缩算法,对于访问较少的数据,可以使用较高级别的压缩方式以节约空间。
更多内容建议参考官方文档:http://docs.oracle.com/database/121/CNCPT/schemaob.htm#CNCPT88859
Oracle——分区表
标签:
原文地址:http://blog.csdn.net/anxpp/article/details/51869335