首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Oracle 19C入门到精通之表分区

Oracle是最早支持物理分区的数据库管理系统供应商,表分区的功能是在Oracle 9.0版本中推出的。分区功能能够改善应用程序的性能、可管理性和可用性,是数据库管理中的一项非常关键的技术。尤其在今天,数据库应用系统的规模越来越大,还有海量数据的数据仓库系统。因此,几乎所有的Oracle数据库都通过使用分区功能来简化数据库的日常管理维护工作。

使用分区技术有如下优点:

减少维护工作量。独立管理每个分区比管理单张大表要轻松得多。

增强数据库的可用性。如果表的一个或几个分区由于系统故障而不能被使用,那么表其余的分区仍然可以使用;如果系统故障只影响表的一部分分区,那么,只有这部分分区需要修复,这就比修复整张大表耗费的时间少许多。

均衡I/O,减少竞争。通过把表的不同分区分配到不同的磁盘来平衡I/O改善性能。

分区对用户保持透明。最终用户感觉不到分区的存在。

提高查询速度。对大表的查询、增加、修改等操作可以分解到表的不同分区中来并行执行,这样就可以加快运行速度,对数据仓库的TP查询尤其有用。

分区技术主要包括表分区和索引分区。

1. 创建表分区

1.1. 范围分区

创建范围分区的关键字是RANGE,创建该分区后,其中的数据可以根据分区键值指定的范围进行分布,当数据在范围内被均匀分布时,性能最好。

当表结构采用范围分区时,首先要考虑分区的列应该符合范围分区的方法;其次要考虑列的数据值的取值范围;最后考虑列的边界问题。

创建一个商品零售表,为该表按照销售日期所在的季度创建4个分区,代码如下:

create table ware_retail_part  --创建一个描述商品零售的数据表

(

id integer primary key,      --销售编号

retail_date date,            --销售日期

ware_name varchar2(50)       --商品名称

)

partition by range(retail_date)

(

--2023年第一个季度为par_01分区

partition par_01 values less than(to_date('2023-04-01','yyyy-mm-dd')) tablespace TBS_TEST_1,

--2023年第二个季度为par_02分区

partition par_02 values less than(to_date('2023-07-01','yyyy-mm-dd')) tablespace TBS_TEST_1,

--2023年第三个季度为par_03分区

partition par_03 values less than(to_date('2023-10-01','yyyy-mm-dd')) tablespace TBS_TEST_2,

--2023年第四个季度为par_04分区

partition par_04 values less than(to_date('2024-01-01','yyyy-mm-dd')) tablespace TBS_TEST_2

);

向表ware_retail_part中插入3条记录,代码如下:

insert into ware_retail_part values(1,to_date('2023-01-20','yyyy-mm-dd'),'平板电脑');

insert into ware_retail_part values(2,to_date('2023-04-15','yyyy-mm-dd'),'智能手机');

insert into ware_retail_part values(3,to_date('2023-07-25','yyyy-mm-dd'),'笔记本电脑');

在向ware_retail_part表中插入若干条记录之后,就可以通过分区表(即进行了分区的数据表)来查询数据了。这种方式的查询速度要比从整张表中查询快得多。

--查询数据表ware_retail_part的分区par_02中的全部记录

select * from ware_retail_part partition(par_02);

RANGE分区的字段可以是两个或者多个;

创建一个商品零售表,为该表按照销售编号和销售日期的组合创建3个分区,代码如下:

create table ware_retail_part2     --创建一个描述商品零售的数据表

(

id integer primary key,           --销售编号

retail_date date,                 --销售日期

ware_name varchar2(50)            --商品名称

)

partition by range(id,retail_date)  --按照销售序号和销售日期分区

(

--第一个分区par_01

partition par_01 values less than (10000, to_date('2023-12-01', 'yyyy-mm-dd')) tablespace TBS_TEST_1,

--第二个分区par_02

partition par_02 values less than (20000, to_date('2024-12-01', 'yyyy-mm-dd')) tablespace TBS_TEST_1,

--第三个分区par_03

partition par_03 values less than (maxvalue, maxvalue) tablespace TBS_TEST_2);

在上述例子中,partition by range(id,retail_date)作为分区方法,id和retail_date作为分区键,即按销售编号和销售日期的组合来进行区分。语句“partition par_01 values less than (10000, to_date('2023-12-01', 'yyyy-mm-dd')) tablespace TBS_TEST_1”表示一个分区的定义,当插入记录的销售日期小于2023年12月1日,并且销售编号小于10000时,将把该记录划为分区par_01并存储在TBS_TEST_1表空间上。

2. 散列分区

HASH分区也叫作散列分区,是在列的取值难以确定的情况下采用的分区方法。例如,按照身份证号进行分区,就很难确定身份证号的分区范围。HASH实际上是一种函数算法,当向表中插入数据时,系统会自动根据当前分区列的值计算出HASH值,然后确定应该将该行存储于哪个表空间中。

HASH分区通过指定分区编号将数据均匀分布在磁盘设备上,使得这些分区大小一致。这充分降低了I/O磁盘争用的情况,但是该分区方法对于范围查询或不等式查询起不到优化的作用。一般来说,下面几种情况可以采用HASH分区:

HASH分区可以由HASH键来分布。

DBA无法获知具体的数据值。

数据的分布由Oracle处理。

每个分区有自己的表空间。

创建一个商品零售表,将该表id列的值根据自身情况散列地存储在指定的两个表空间中,代码如下:

create table ware_retail_part3         --创建一个描述商品零售的数据表

(

id integer primary key,              --销售编号

retail_date date,                    --销售日期

ware_name varchar2(50)               --商品名称

)

partition by hash(id)

(

partition par_01 tablespace TBS_TEST_1,  --创建par_01分区

partition par_02 tablespace TBS_TEST_2   --创建par_02分区

);

在为商品零售表ware_retail_part3创建了两个HASH分区之后,接下来向该表中插入一条记录。

--向表ware_retail_part3中插入一条记录

insert into ware_retail_part3 values(99,to_date('2023-11-11','yyyy-mm-dd'),'台式电脑');

上述插入的记录到底被分配到哪个分区中呢?用户无法直接判断,而是由Oracle系统通过计算id的HASH值(这里是99),然后系统按照均匀分布的原则自动分配的。通过SELECT语句来查询该记录所在的分区:

select * from ware_retail_part3 partition(par_01);

select * from ware_retail_part3 partition(par_02);

在上述若干个创建表分区的例子中,都为表分区指定了名称,在Oracle中,可以实现由系统自动分配分区名。

创建一个表person,然后为该表创建HASH列分区(分区列为id),要求创建的两个分区由系统自动生成分区名,并分别放置在表空间TBS_TEST_1和TBS_TEST_2中,代码如下:

create table person       --创建一个描述个人信息的表

(

id number primary key,  --个人的编号

name varchar2(20),      --姓名

sex varchar2(2)         --性别

)

partition by hash(id)     --使用id作为HASH分区的键值

partitions 2              --创建两个分区,分区名由系统自动给出

store in(TBS_TEST_1,TBS_TEST_2);  --指定两个不同的命名空间

在上述例子中,HASH分区表的每个分区均保存在不同的表空间中,这样HASH数据也就被存储在不同的表空间中了。

在创建HASH分区表时,还可以指定所有分区的初始分配空间。

创建一个goods表,为该表创建HASH列分区(分区列为id),并为创建的表分区指定初始化空间,大小为2048 KB,代码如下:

create table goods      --定义包含商品信息的表

(

id number,            --编号

goodname varchar2(50) --名称

)

storage(initial 2048k)  --定义表分区的初始化空间大小为2048

partition by hash(id)   --创建id列作为分区键的HASH表分区

(

partition par1 tablespace TBS_TEST_1,  --表分区par1

partition par2 tablespace TBS_TEST_2   --表分区par2

);

在上述例子中,指定了各个分区的名称及其所存储的表空间,所有分区的大小都继承表空间的初始分配参数值,即2048 KB。

3. 列表分区

列表分区关键字是LIST,如果表的某个列的值可以枚举,则可以考虑对表进行列表分区。例如,客户表clients可以按照客户所在的省份进行分区,该表的列表分区可以分为partition shandong(山东省)、partition guangdong(广东省)与partiton yunnan(云南省)等。

创建一个用于保存客户信息的表clients,以province列为分区键创建列表分区,代码如下:

create table clients          --创建客户表

(

id integer primary key,     --客户编号

name varchar2(50),          --客户名称

province varchar2(20)       --客户所在省份

)

partition by list(province)   --以province列为分区键创建列表分区

(

partition shandong values('山东省'),   --山东省份区

partition guangdong values('广东省'),  --广东省份区

partition yunnan values('云南省')      --云南省份区

);

在为客户表clients创建了列表分区之后,接下来向该表中插入一条记录。

--向表clients中插入一条记录

insert into clients values(19,'顺达','山东省');

由于插入记录的province字段的值为“山东省”,因此该记录被存储到名称为shandong的表分区中。通过SELECT语句来查询shandong表分区中的记录,查询结果如图所示:

select * from clients partition(shandong);

4. 组合分区

综合运用两种数据分区方法,可以进行组合分区。首先用第一种数据分区方法对表格进行分区,然后用第二种数据分区方法对每个分区进行二次分区。

Oracle支持6种组合分区方案:组合范围和范围分区、组合列表和范围分区、组合范围和散列分区、组合范围和列表分区、组合列表和列表分区、组合列表和散列分区。

当前的Oracle仅支持对索引组织表(索引和数据一起的表格)进行范围分区、列表分区或散列分区,但不支持对其进行组合分区。

创建一个保存人员信息的数据表person2,然后创建3个范围分区,每个分区又包含两个子分区,子分区没有名称,由系统自动生成,并要求将其分布在两个指定的表空间中,代码如下:

create table person2                       --创建一个描述个人信息的表

(

id number primary key,                    --个人的编号

name varchar2(20),                        --姓名

sex varchar2(2)                           --性别

)

partition by range(id)                      --以id作为分区键创建范围分区

subpartition by hash(name)                  --以name列作为分区键创建HASH子分区

subpartitions 2 store in(TBS_TEST_1,TBS_TEST_2) --HASH子分区共有两个,分别存储在两个不同的命名空间中

(

partition par1 values less than(5000),    --范围分区,id小于5000

partition par2 values less than(10000),   --范围分区,id小于10000

partition par3 values less than(maxvalue) --范围分区,id不小于10000

);

上述代码首先按照范围进行分区,然后对子分区按照HASH进行分区,根据name列的HASH值确定该行分布在TBS_TEST_1或TBS_TEST_2某个表空间上。

5. Interval分区

Interval分区的关键字是INTERVAL,它是范围分区的一种增强功能,可以实现equi_sized范围分区的自动化。该方法创建的分区作为元数据,只有最开始的分区是永久分区。随着数据的增加会分配更多的部分,并自动创建新的分区和本地索引。

创建一个saleRecord表,为该表创建Interval分区,代码如下:

create table saleRecord

(

id number primary key,                --编号

goodsname varchar2(50),               --商品名称

saledate date,                        --销售日期

quantity number                       --销售量

)

partition by range(saledate)          --以销售日期为分区键

interval (numtoyminterval(1,'year'))  --Interval分区实现按年份进行自动分区

(

--设置分区键值日期小于2023-01-01

partition par_fist values less than (to_date('2023-01-01','yyyy-mm-dd'))

);

在上述代码中,函数NUMTOYMINTERVAL的功能是将数字转换成YEAR或者MONTH。

进行Interval分区的表格有传统的范围部分和自动生成的Interval部分。对于已经进行了范围分区的表格,可以通过使用ALTER TABLE命令的SET INTERVAL选项扩展成为Interval分区的表格。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O7kBimgVXOpLv6VXuZZtwrUQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券