1.什么是分区
分区的实质是把一张大表的数据按照某种规则使用多张子表来存储。然后这多张子表使用统一的表名对外提供服务,子表实际对用户不可见。类似于在多张子表上建立一个视图,然后用户直接使用该视图来访问数据。
2.为什么要使用分区
当一张表的数据量到达上亿行的时候,表的性能会严重降低,这个时候就需要用到分区了,通过划分成多个小表,并在每个小表上建立本地索引可以大大缩小索引数据文件的大小,从而更快的定位到目标数据来提升访问性能。
分区除了可以用来提升访问性能外,还因为可以指定分区所使用的表空间,因此也用来做数据的生命周期管理。当前需要频繁使用的活跃数据可以放到访问速度更快但价格也更贵的存储设备上,而2、3年前的历史数据,或者叫冷数据可以放到更廉价、速度更低的设备上。从而降低存储费用。
3.简单分区
常用的分区方法有RANGE、HASH、LIST 3 种。
range分区通常用来对时间或数字进行分区,list分区用来把不相关的数据组织到一起,hash让数据均匀的分布到各个分区中。另外为了方便对范围分区进行管理,oracle还提供了range分区的增强类型interval(间隔)分区,当有新写入的数据的分区值超过了当前分区范围的最大值的时候,它会以分区范围的当前最大值为基数,以指定的interval 为区间,自动创建一个新分区,具体使用案例见下文。
范围分区语法图
列表分区语法图
individual_hash_partitions::=
hash_partitions_by_quantity::=
案例:
想想这样一种情况:假设我们需要对某张表按月为单位进行分区,也许我们可以提前建好近1年的分区,但是1年的时间一过,我们就需要再添加分区了,如果没有每天定时查看分区数是否足够的话,那么就会因为分区不存在而报错,如果使用间隔分区表的话,dbms会根据分区字段的值自动添加分区。
如下例,建表的时候指定了5个分区,且分区间隔为1年,目前库里面最大的分区p2020的边界是少于2021-01-01日(范围分区的指定范围为左闭右开,即边界不包括values less than指定的值)
create table RANGE_INTERVAL(id int, name varchar2(500), update_time date)
partition by range(update_time)
interval (numtoyminterval(1,'year') )
(partition p2016 values less than (to_date('2017-01-01','yyyy-mm-dd')) compress for oltp tablespace che_data pctfree 5,
partition p2017 values less than (to_date('2018-01-01','yyyy-mm-dd')) compress for oltp pctfree 5,
partition p2018 values less than (to_date('2019-01-01','yyyy-mm-dd')) compress for oltp pctfree 5,
partition p2019 values less than (to_date('2020-01-01','yyyy-mm-dd')) compress for oltp pctfree 5,
partition p2020 values less than (to_date('2021-01-01','yyyy-mm-dd')) compress for oltp
);
表建好之后,我们看一下dbms的元数据,一个5个分区,且都不是间隔分区
insert into RANGE_INTERVAL
select 1, 'xixi' name , sysdate + interval '1' year from dual;
插入数据后,再次查看dbms的元数据
可以看到多了一个分区。
4.二级分区
二级分区是可以在分区里再次根据指定的字段划分子分区,range、hash、list这三种分区类型可以两两组合形成二级分区,也可以和自己组合形成二级分区。
混合范围分区::=
混合列表分区::=
混合hash分区::=
子分区语法图
范围子分区语法图
列表子分区语法图
hash子分区语法图
4.1hash-hash二级分区使用示例
create table PPU_CELLPHONE_BAK partition by hash (data_source_id) subpartition by hash(ENCRYPT_ID )
subpartitions 5 partitions 6