Oracle表分区(范围分区、hash列分区、列表分区、interval分区)的创建和修改维护


通过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

分区

  1. 减少维护工作量
  2. 增强数据库可用性
  3. 均衡I/O
  4. 分区对用户透明,对其存在无感知
  5. 提高查询速度

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(5067   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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章