概述

此实验关于Oracle Partitioning选件。

此实验申请地址在这里。

实验帮助在这里。

实验宣称需要2小时40分,实际用了4个小时。

Introduction

About this Workshop

Oracle 提供了全面的分区方案来满足每个业务需求。 此外,由于它在 SQL 语句中完全透明,因此分区可以用于任何应用程序,从打包的 OLTP 应用程序到数据仓库。 在本次研讨会中,我们将探索各种分区类型及其相应的用例。

预计工作坊时间:2 小时 40 分钟

About Oracle Partitioning

Oracle 分区增强了大型数据库的可管理性、性能和可用性。 它提供了全面的分区方法来满足不同的业务需求。 我们可以在事务、数据仓库和混合工作负载应用程序上应用数据库分区,而无需更改任何代码。 我们可以对大型表和索引使用分区,以使它们成为更小的对象,可以在更高级的粒度级别上进行管理和访问。

在 Oracle 数据库中对大型表和索引进行分区可确保为每个业务需求提供最佳方法,并且可以增强几乎所有数据库应用程序的可管理性、性能和可用性。 分区允许将表和索引分解为更小的物理块,同时保持单个对象的逻辑视图。

Challenges with growing Data Volume

让我们考虑一下金融服务部门,尤其是零售银行业务,每次我们进行借记、贷记、定期存款、定期存款、汽车 EMI 支付、水电费支付等交易时。 根据 2021 年 12 月 31 日的商业标准报告,它在交易主表中生成一条记录,并且数据呈指数级增长。印度的数字交易量从 2017 财年的 108.5 亿增长到 21 财年的 555.4 亿,复合 年增长率为50.42%。 因此,随着数据量的增长,我们可以将很大一部分历史数据归档到归档存储中,以便按需检索; 然而,即使我们考虑当前财政年度的数据,它在银行层面也有数百万条记录。 在此级别运行查询将花费大量时间并影响整体性能。 最好根据业务需求将数据划分为更小的单元。 大表难以管理,因此可以将大型数据库和索引拆分成更小、更易于管理的部分。 例如,如果我们的数据库中有太多事件,我们可以轻松地将该表划分为基于区域和月份的事件。

分区的好处:

通过仅处理相关数据来提高性能。通过最适当地存储数据来降低成本。它易于实施,无需更改应用程序和查询。它是成千上万的 Oracle 客户使用的成熟且经过充分验证的特性。分区减少了从存储中检索的数据量它仅对相关分区执行操作透明地提高查询性能并优化资源利用率

分区支持数据管理操作,例如。

数据加载、连接和修剪,索引创建和重建,优化器统计管理,备份和恢复

Objectives

在本次研讨会中,您将学习如何创建以下分区。

范围分区间隔分区列表分区哈希分区自动列表分区只读分区多列列表分区将非分区表转换为分区表

Learn More

Partitioning whitepaper Oracle Database Editions

Get started

实验环境生成后,单击“View Login Info”可以看到登录信息:

本实验使用的数据库是ADW,即自治数据仓库。

实际上,脚本可以在任何Oracle数据库上运行,而且测试数据很少,最多也就100条。大部分的实验来自Oracle LiveSQL。

Lab 1: Connect to you Autonomous Database

原实验是用SQL Developer Web,为了速度和方便,我还是使用了SQL Developer。配置过程略。

Lab 2: Range Partitioning

Introduction

范围分区根据您为每个分区建立的分区键值范围将数据映射到分区。 它是与日期一起使用的最常见的分区类型。 例如,您可能希望将销售数据划分为每月分区。 CREATE TABLE 语句的 PARTITION BY RANGE 子句指定表或索引是范围分区的。 PARTITION 子句标识各个分区范围,并且 PARTITION 子句的可选子句可以选择特定于分区段的物理属性和其他属性。

预计实验时间:20 分钟

About Range Partitioning

范围分区是最常见的分区类型,与日期一起使用。 对于以日期列作为分区键的表,January-2010 分区将包含分区键值从 2010 年 1 月 1 日到 2010 年 1 月 31 日的行。

每个分区都有一个 VALUES LESS THAN 子句,该子句指定分区的非包含上限(因为是小于而非小于等于)。 任何等于或高于此文字的分区键值都将添加到下一个更高的分区。 除第一个分区外,所有分区都具有由前一个分区的 VALUES LESS THAN 子句指定的隐式下限。

可以为最高分区定义 MAXVALUE 文字。 MAXVALUE 表示一个虚拟的无限值,其排序高于分区键的任何可能值,包括 NULL 值。

Features

在 Oracle 8.0 引入Range Partition 是单级分区时间数据的理想选择数据可以根据需要拆分和合并

Sales data based on specific date range

以下是有关美国零售业的一些有趣事实,美国电子商务行业专家预计销售数据将以两位数增长,到 2021 年增长 17.9% 至 9333 亿美元。 电子商务渗透率将继续增加,比 2019 年翻一番还多,到 2025 年达到 23.6%。这意味着不断增长的客户和销售数据量以及其可管理性带来的挑战。 管理如此大量的按时间顺序或销售数据的解决方案是根据日期范围对其进行分区或使用范围分区。

Task 1: Create Range Partitioned Table

让我们创建范围分区表。 该表使用 sales_date 列的值按范围分区。 分区界限由 VALUES LESS THAN 子句确定。

CREATE TABLE sales_range_partition (

product_id NUMBER(6),

customer_id NUMBER,

channel_id CHAR(1),

promo_id NUMBER(6),

sale_date DATE,

quantity_sold INTEGER,

amount_sold NUMBER(10, 2)

)

PARTITION BY RANGE (

sale_date

)

( PARTITION sales_q1_2014

VALUES LESS THAN ( TO_DATE('01-APR-2014', 'dd-MON-yyyy') ),

PARTITION sales_q2_2014

VALUES LESS THAN ( TO_DATE('01-JUL-2014', 'dd-MON-yyyy') ),

PARTITION sales_q3_2014

VALUES LESS THAN ( TO_DATE('01-OCT-2014', 'dd-MON-yyyy') ),

PARTITION sales_q4_2014

VALUES LESS THAN ( TO_DATE('01-JAN-2015', 'dd-MON-yyyy') )

);

使用此 SQL 查询显示表中的分区。

SET SQLFORMAT ANSICONSOLE

SELECT

table_name,

partition_name,

partition_position,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_RANGE_PARTITION';

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

SALES_RANGE_PARTITION SALES_Q1_2014 1 TO_DATE(' 2014-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q2_2014 2 TO_DATE(' 2014-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q3_2014 3 TO_DATE(' 2014-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q4_2014 4 TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

新增分区:

ALTER TABLE sales_range_partition ADD PARTITION sales_q1_2015

VALUES LESS THAN ( TO_DATE('01-APR-2015', 'dd-MON-yyyy') );

添加新分区后显示表中的分区。

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

SALES_RANGE_PARTITION SALES_Q1_2014 1 TO_DATE(' 2014-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q2_2014 2 TO_DATE(' 2014-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q3_2014 3 TO_DATE(' 2014-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q4_2014 4 TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

SALES_RANGE_PARTITION SALES_Q1_2015 5 TO_DATE(' 2015-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

将值插入表中。

INSERT INTO sales_range_partition VALUES (1001,100,'A',150,'10-FEB-2014',500,2000);

INSERT INTO sales_range_partition VALUES (1002,110,'B',180,'15-JUN-2014',100,1000);

INSERT INTO sales_range_partition VALUES (1001,100,'A',150,'20-AUG-2014',500,2000);

COMMIT;

显示表中指定分区的数据。

SELECT * FROM sales_range_partition PARTITION(sales_q1_2014);

PRODUCT_ID CUSTOMER_ID CHANNEL_ID PROMO_ID SALE_DATE QUANTITY_SOLD AMOUNT_SOLD

1001 100 A 150 10-FEB-14 500 2000

显示表中的所有数据。

SELECT * FROM sales_range_partition;

PRODUCT_ID CUSTOMER_ID CHANNEL_ID PROMO_ID SALE_DATE QUANTITY_SOLD AMOUNT_SOLD

1001 100 A 150 10-FEB-14 500 2000

1002 110 B 180 15-JUN-14 100 1000

1001 100 A 150 20-AUG-14 500 2000

Task 2: Cleanup

DROP TABLE sales_range_partition;

Learn More

Range Partitioning Database VLDB and Partitioning Guide

Lab 3: Interval Partitioning

Introduction

间隔分区是范围分区的扩展,其中数据库表分区是基于间隔完成的,而不仅仅是日期本身。 CREATE TABLE 语句的 INTERVAL 子句为表建立间隔分区。 您必须使用 PARTITION 子句指定至少一个范围分区。 范围分区键值决定了范围分区的高值,称为过渡点。 数据库会自动为超出该转换点的数据创建间隔分区。 每个区间分区的下边界是前一个范围或区间分区的非包含上边界。

预计实验时间:20 分钟

Features

与 Oracle 11g 一起引入范围分区的扩展等大小范围分区的完全自动化复合级别分区的一部分差异区间和范围分区系统生成的间隔名称无需任何分区管理

Analyze Business Data at Various Intervals

当业务分析师想要查看每日、每月、每季度或每年的销售数据时,例如,在金融服务或零售行业中,根据间隔对数据进行分区会更容易。 随着数据的增长,分区会不断自动创建。

Task 1: Create Interval Partitioned Table

让我们创建间隔分区表。 以下示例指定两个分区,其间隔宽度为一个月。

CREATE TABLE interval_par_demo (

start_date DATE,

store_id NUMBER,

inventory_id NUMBER(6),

qty_sold NUMBER(3)

)

PARTITION BY RANGE (

start_date

) INTERVAL ( numtoyminterval(1, 'MONTH') ) ( PARTITION interval_par_demo_p2

VALUES LESS THAN ( TO_DATE('1-7-2007', 'DD-MM-YYYY') ),

PARTITION interval_par_demo_p3

VALUES LESS THAN ( TO_DATE('1-8-2007', 'DD-MM-YYYY') )

);

Task 2: Auto Generate Interval Partitions

插入记录:

insert into interval_par_demo (start_date, store_id, inventory_id, qty_sold)

values ( '15-AUG-07', 1, 1, 1);

insert into interval_par_demo (start_date, store_id, inventory_id, qty_sold)

values ( '15-SEP-07', 1, 1, 1);

查看 USER_TAB_PARTITIONS 表中的数据:

SELECT

table_name,

partition_name,

partition_position,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'INTERVAL_PAR_DEMO'

ORDER BY

partition_name;

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

INTERVAL_PAR_DEMO INTERVAL_PAR_DEMO_P2 1 TO_DATE(' 2007-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

INTERVAL_PAR_DEMO INTERVAL_PAR_DEMO_P3 2 TO_DATE(' 2007-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

INTERVAL_PAR_DEMO SYS_P1891 3 TO_DATE(' 2007-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

INTERVAL_PAR_DEMO SYS_P1892 4 TO_DATE(' 2007-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

这里 SYS_P1891 和 SYS_P1892 是基于间隔自动生成的分区。 让我们验证新创建的分区中的数据。 请注意,自动生成的分区名称可能因您的实例而异。

SELECT * FROM interval_par_demo PARTITION(SYS_P1891);

START_DATE STORE_ID INVENTORY_ID QTY_SOLD

15-AUG-07 1 1 1

SELECT * FROM interval_par_demo PARTITION(SYS_P1892);

START_DATE STORE_ID INVENTORY_ID QTY_SOLD

15-SEP-07 1 1 1

Task 3: Cleanup

drop table interval_par_demo purge;

Learn More

Interval Partitioning Database VLDB and Partitioning Guide

Lab 4: List Partitioning

Introduction

列表分区使您能够通过为每个分区的描述中的每个分区键指定离散值列表来显式控制行映射到分区的方式。 列表分区的优点是可以对无序和不相关的数据集进行分组和组织。 对于以 region 列作为分区键的表,East Sales Region 分区可能包含 New York、Virginia 和 Florida 值。 创建列表分区的语义类似于创建范围分区的语义。

创建列表分区的语义类似于创建范围分区的语义。 您在 CREATE TABLE 语句中指定 PARTITION BY LIST 子句来创建列表分区。 分区键可以是用于列表分区的表中的一个或多个列名。

预计实验时间:20 分钟

与范围分区不同,使用列表分区的分区之间没有明显的顺序感。 您还可以指定一个默认分区,将不映射到任何其他分区的行映射到该分区。

Features

随 Oracle 9.0 引入List Partition 是单级分区数据以值列表的形式组织每个列表有一个或多个无序的不同值非常适合分割不同的值,例如区域

Weather forecasting or sales forecasting based on regional list

天气预报是通过收集有关给定地点当前大气的定量数据并使用气象学来预测大气将如何变化来进行的。 天气预报是经济的一部分。 例如,2009 年,美国在天气预报上花费了大约 51 亿美元,产生的收益估计是原来的六倍。 数据量不断增长,分析以前的区域数据可能是性能密集型的。 由于天气数据具有地理位置、日期、温度和湿度的变化,因此这是基于区域值列表或使用列表分区对数据进行分区的好案例。 另一个很好的例子是基于区域划分销售数据以用于业务报告,如下面的任务列表所示。

Task 1: Create List Partitioned Table

创建列表分区表:

CREATE TABLE sales_by_region (

product_id NUMBER(6),

quantity_sold INTEGER,

sale_date DATE,

store_name VARCHAR(30),

state_code VARCHAR(2)

)

PARTITION BY LIST (state_code)

(

PARTITION region_east

VALUES ('CT','MA','MD','ME','NH','NJ','NY','PA','VA'),

PARTITION region_west

VALUES ('AZ','CA','CO','NM','NV','OR','UT','WA'),

PARTITION region_south

VALUES ('AL','AR','GA','KY','LA','MS','TN','TX'),

PARTITION region_central

VALUES ('IA','IL','MO','MI','ND','OH','SD')

);

查看 user_tab_partitions 表中的数据:

SELECT

table_name,

partition_name,

partition_position,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_BY_REGION';

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

SALES_BY_REGION REGION_EAST 1 'CT', 'MA', 'MD', 'ME', 'NH', 'NJ', 'NY', 'PA', 'VA'

SALES_BY_REGION REGION_WEST 2 'AZ', 'CA', 'CO', 'NM', 'NV', 'OR', 'UT', 'WA'

SALES_BY_REGION REGION_SOUTH 3 'AL', 'AR', 'GA', 'KY', 'LA', 'MS', 'TN', 'TX'

SALES_BY_REGION REGION_CENTRAL 4 'IA', 'IL', 'MO', 'MI', 'ND', 'OH', 'SD'

Task 2: Add New Partitions

-- 向表中添加一个新分区。

ALTER TABLE sales_by_region ADD PARTITION region_nonmainland VALUES ('HI','PR');

-- 在表中添加新分区以容纳 NULL 值。

ALTER TABLE sales_by_region ADD PARTITION region_null VALUES (NULL);

-- 为不映射到任何其他分区的值添加一个新分区到表中。

ALTER TABLE sales_by_region ADD PARTITION VALUES (DEFAULT);

-- 添加新分区后显示表中的分区。

SELECT

table_name,

partition_name,

partition_position,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_BY_REGION';

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

SALES_BY_REGION REGION_EAST 1 'CT', 'MA', 'MD', 'ME', 'NH', 'NJ', 'NY', 'PA', 'VA'

SALES_BY_REGION REGION_WEST 2 'AZ', 'CA', 'CO', 'NM', 'NV', 'OR', 'UT', 'WA'

SALES_BY_REGION REGION_SOUTH 3 'AL', 'AR', 'GA', 'KY', 'LA', 'MS', 'TN', 'TX'

SALES_BY_REGION REGION_CENTRAL 4 'IA', 'IL', 'MO', 'MI', 'ND', 'OH', 'SD'

SALES_BY_REGION REGION_NONMAINLAND 5 'HI', 'PR'

SALES_BY_REGION REGION_NULL 6 NULL

SALES_BY_REGION SYS_P1893 7 DEFAULT

7 rows selected.

-- 将新值添加到分区键列表中。

ALTER TABLE sales_by_region MODIFY PARTITION region_central ADD VALUES ('OK','KS');

-- 修改分区后显示表中的分区。

SELECT

table_name,

partition_name,

partition_position,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_BY_REGION';

TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE

SALES_BY_REGION REGION_EAST 1 'CT', 'MA', 'MD', 'ME', 'NH', 'NJ', 'NY', 'PA', 'VA'

SALES_BY_REGION REGION_WEST 2 'AZ', 'CA', 'CO', 'NM', 'NV', 'OR', 'UT', 'WA'

SALES_BY_REGION REGION_SOUTH 3 'AL', 'AR', 'GA', 'KY', 'LA', 'MS', 'TN', 'TX'

SALES_BY_REGION REGION_CENTRAL 4 'IA', 'IL', 'MO', 'MI', 'ND', 'OH', 'SD', 'OK', 'KS'

SALES_BY_REGION REGION_NONMAINLAND 5 'HI', 'PR'

SALES_BY_REGION REGION_NULL 6 NULL

SALES_BY_REGION SYS_P1893 7 DEFAULT

7 rows selected.

-- 将值插入表中。

INSERT INTO sales_by_region VALUES (1001,100,'25-AUG-2014','My Store MA','MA');

INSERT INTO sales_by_region VALUES (1002,200,'26-AUG-2014','My Store OK','OK');

COMMIT;

-- 显示表中的所有数据。

SELECT * FROM sales_by_region;

PRODUCT_ID QUANTITY_SOLD SALE_DATE STORE_NAME STATE_CODE

1001 100 25-AUG-14 My Store MA MA

1002 200 26-AUG-14 My Store OK OK

Task 3: Partitioned Data by Partition Name

显示表中指定分区的数据。

SELECT * FROM sales_by_region PARTITION(region_east);

PRODUCT_ID QUANTITY_SOLD SALE_DATE STORE_NAME STATE_CODE

1001 100 25-AUG-14 My Store MA MA

Task 4: Cleanup

drop table sales_by_region purge;

Learn More

List Partitioning Database VLDB and Partitioning Guide

Lab 5: Hash Partitioning

Introduction

散列分区根据 Oracle 的散列算法将数据映射到分区到您识别的分区键。 散列算法在分区之间均匀分布行,使分区大小大致相同。 复合 hash-* 分区允许沿两个维度进行散列分区。 复合 hash-hash 分区策略在复合 hash-* 分区表中具有最大的商业价值。 这种技术有利于沿二维进行分区连接。

预计实验室时间:20 分钟

哈希分区是跨设备均匀分布数据的理想方法。 哈希分区也是范围分区的一种易于使用的替代方案,主要是在分区的数据不是历史数据或没有明显的分区键时。

Features

随 Oracle 8.1 引入哈希分区是单级分区根据分区键的哈希值放置数据数据均等分布的理想选择分区数应该是 2 的幂,以实现均匀的数据分布

Data partition based on product list or hash values

在常规电子商务网站中,产品列表、过滤和排序决定了客户浏览产品目录的难易程度。 在 UI 专家的可用性测试中,客户购买组织良好且易于查找的产品的可能性很大。 下面是一个简单的示例,说明如何为板球运动装备对在线商店数据进行哈希分区,其中每个(球棒、球等)都被命名为表空间。

CREATE TABLE cricketset (

id NUMBER,

name VARCHAR2(60)

)

PARTITION BY HASH ( id ) PARTITIONS 7 STORE IN ( bat, ball, stumps, wicket, gloves, pads, guards );

Task 1: Create Interval Hash Partitioned Table

让我们创建一个以客户id为哈希值的间隔哈希分区表,对2016年之前和2016年之后的数据进行分区。

-- 一级是间隔分区,二级是哈希分区

CREATE TABLE sales_interval_hash (

prod_id NUMBER(6),

cust_id NUMBER,

time_id DATE,

channel_id CHAR(1),

promo_id NUMBER(6),

quantity_sold NUMBER(3),

amount_sold NUMBER(10, 2)

)

PARTITION BY RANGE ( time_id ) INTERVAL ( numtoyminterval(1, 'MONTH') )

SUBPARTITION BY HASH ( cust_id ) SUBPARTITIONS 4

( PARTITION before_2016

VALUES LESS THAN ( TO_DATE('01-JAN-2016', 'dd-MON-yyyy') )

);

使用此 SQL 查询显示表中的分区/子分区。 系统生成的名称已分配给分区和子分区。

SELECT

substr(table_name, 1, 32),

substr(partition_name, 1, 32),

substr(subpartition_name, 1, 32)

FROM

user_tab_subpartitions

WHERE

table_name = 'SALES_INTERVAL_HASH';

SUBSTR(TABLE_NAME,1,32) SUBSTR(PARTITION_NAME,1,32) SUBSTR(SUBPARTITION_NAME,1,32)

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1894

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1895

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1896

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1897

Task 2: Insert Data and View Partitioned Data

-- 将数据插入 sales_interval_hash 表

-- 第3和第4条记录位于同一分区,不同子分区

INSERT INTO sales_interval_hash VALUES (2105, 101, '15-FEB-16', 'B', 19, 10, 300.00) ;

INSERT INTO sales_interval_hash VALUES (2105, 102, '21-APR-16', 'C', 12, 100, 2000.00) ;

INSERT INTO sales_interval_hash values (1200, 155, '31-MAY-16', 'D', 20, 300, 3600.00);

INSERT INTO sales_interval_hash values (1400, 165, '31-MAY-16', 'E', 15, 100, 4000.00);

INSERT INTO sales_interval_hash VALUES (2105, 125, '05-AUG-16', 'B', 16, 40, 8500.00);

INSERT INTO sales_interval_hash VALUES (2105, 302, '15-OCT-16', 'A', 11, 75, 4350.00);

COMMIT;

-- 显示表格中的数据

select * from sales_interval_hash;

PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD

2105 101 15-FEB-16 B 19 10 300

2105 102 21-APR-16 C 12 100 2000

1200 155 31-MAY-16 D 20 300 3600

1400 165 31-MAY-16 E 15 100 4000

2105 125 05-AUG-16 B 16 40 8500

2105 302 15-OCT-16 A 11 75 4350

6 rows selected.

-- 使用此 SQL 查询显示表中的分区和子分区。 请注意,表的结构随着新数据的变化而变化。

-- 2016 年的每个唯一 time_id 都会生成一个包含四个子分区的新分区。

SELECT

substr(table_name, 1, 32),

substr(partition_name, 1, 32),

substr(subpartition_name, 1, 32)

FROM

user_tab_subpartitions

WHERE

table_name = 'SALES_INTERVAL_HASH';

SUBSTR(TABLE_NAME,1,32) SUBSTR(PARTITION_NAME,1,32) SUBSTR(SUBPARTITION_NAME,1,32)

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1894

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1895

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1896

SALES_INTERVAL_HASH BEFORE_2016 SYS_SUBP1897

SALES_INTERVAL_HASH SYS_P1902 SYS_SUBP1898

SALES_INTERVAL_HASH SYS_P1902 SYS_SUBP1899

SALES_INTERVAL_HASH SYS_P1902 SYS_SUBP1900

SALES_INTERVAL_HASH SYS_P1902 SYS_SUBP1901

SALES_INTERVAL_HASH SYS_P1907 SYS_SUBP1903

SALES_INTERVAL_HASH SYS_P1907 SYS_SUBP1904

SALES_INTERVAL_HASH SYS_P1907 SYS_SUBP1905

SALES_INTERVAL_HASH SYS_P1907 SYS_SUBP1906

SALES_INTERVAL_HASH SYS_P1912 SYS_SUBP1908

SALES_INTERVAL_HASH SYS_P1912 SYS_SUBP1909

SALES_INTERVAL_HASH SYS_P1912 SYS_SUBP1910

SALES_INTERVAL_HASH SYS_P1912 SYS_SUBP1911

SALES_INTERVAL_HASH SYS_P1917 SYS_SUBP1913

SALES_INTERVAL_HASH SYS_P1917 SYS_SUBP1914

SALES_INTERVAL_HASH SYS_P1917 SYS_SUBP1915

SALES_INTERVAL_HASH SYS_P1917 SYS_SUBP1916

SALES_INTERVAL_HASH SYS_P1922 SYS_SUBP1918

SALES_INTERVAL_HASH SYS_P1922 SYS_SUBP1919

SALES_INTERVAL_HASH SYS_P1922 SYS_SUBP1920

SALES_INTERVAL_HASH SYS_P1922 SYS_SUBP1921

24 rows selected.

-- 插入 2012 年的新记录

INSERT INTO sales_interval_hash VALUES (2199, 302, '10-OCT-12', 'A', 11, 75, 4350.00);

COMMIT;

-- 按分区查看sales_interval_hash表2016年以前的数据

select * from SALES_INTERVAL_HASH PARTITION(BEFORE_2016);

PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD

2199 302 10-OCT-12 A 11 75 4350

-- 按系统生成的分区查看 sales_interval_hash 表中的数据。 在下面的示例中,SYS_P1912 是系统生成的分区名称。

select * from SALES_INTERVAL_HASH PARTITION(SYS_P1912);

PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD

1200 155 31-MAY-16 D 20 300 3600

1400 165 31-MAY-16 E 15 100 4000

Task 3: Cleanup

drop table sales_interval_hash purge;

Learn More

Interval Hash Partitioning Database VLDB and Partitioning Guide

Lab 6: Auto List Partitioning

Introduction

自动列表分区方法可以按需创建列表分区。 自动列表分区表与常规列表分区表类似,只是该分区表更易于管理。 您可以仅使用已知的分区键值来创建自动列出分区表。 当数据加载到表中时,如果加载的分区键值与任何现有分区都不对应,数据库会自动创建一个新分区。

预计实验时间:20 分钟

自动列表分区是按需自动创建的,自动列表分区方法在概念上类似于当前的间隔分区方法。 CREATE 和 ALTER TABLE SQL 语句使用附加子句进行更新,以指定 AUTOMATIC 或 MANUAL 列表分区。 自动列表分区表在创建时必须至少有一个分区。

Features

数据自动到达时创建分区LIST 分区的扩展系统为自动创建的分区生成的分区名称唯一的要求是没有 DEFAULT 分区

Automatic list partitioning use case

自动列表分区的典型用例是公司目前与来自美国、英国和爱尔兰的客户打交道。 您想根据国家/地区划分您的订单表。 另一个例子是在 IoT(物联网)应用中划分传感器数据,例如湿度、温度、气候、压力和空气质量变化。 这些传感器的测量值发生变化。

Task 1: Create Auto-list Partitioned Table

-- 创建具有一个所需分区的自动列表分区表

CREATE TABLE sales_auto_list (

salesman_id NUMBER(5) NOT NULL,

salesman_name VARCHAR2(30),

sales_state VARCHAR2(20) NOT NULL,

sales_amount NUMBER(10),

sales_date DATE NOT NULL

)

PARTITION BY LIST ( sales_state ) AUTOMATIC ( PARTITION p_cal VALUES ( 'CALIFORNIA' ) );

-- 查看 SALES_AUTO_LIST 表中的数据

SELECT

table_name,

partitioning_type,

autolist,

partition_count

FROM

user_part_tables

WHERE

table_name = 'SALES_AUTO_LIST';

TABLE_NAME PARTITIONING_TYPE AUTOLIST PARTITION_COUNT

SALES_AUTO_LIST LIST YES 1

SELECT

table_name,

partition_name,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_AUTO_LIST';

TABLE_NAME PARTITION_NAME HIGH_VALUE

SALES_AUTO_LIST P_CAL 'CALIFORNIA'

-- 将数据插入 SALES_AUTO_LIST 表

INSERT INTO SALES_AUTO_LIST VALUES(021, 'Mary Smith', 'FLORIDA', 41000, TO_DATE ('21-DEC-2018','DD-MON-YYYY'));

INSERT INTO SALES_AUTO_LIST VALUES(032, 'Luis Vargas', 'MICHIGAN', 42000, TO_DATE ('31-DEC-2018','DD-MON-YYYY'));

COMMIT;

-- 查看 SALES_AUTO_LIST 表中的数据

SELECT * FROM sales_auto_list;

SALESMAN_ID SALESMAN_NAME SALES_STATE SALES_AMOUNT SALES_DATE

21 Mary Smith FLORIDA 41000 21-DEC-18

32 Luis Vargas MICHIGAN 42000 31-DEC-18

-- 查看 USER_PART_TABLES 中的数据

SELECT

table_name,

partitioning_type,

autolist,

partition_count

FROM

user_part_tables

WHERE

table_name = 'SALES_AUTO_LIST';

TABLE_NAME PARTITIONING_TYPE AUTOLIST PARTITION_COUNT

SALES_AUTO_LIST LIST YES 3

-- 将数据插入 SALES_AUTO_LIST 表

INSERT INTO SALES_AUTO_LIST VALUES(015, 'Simone Blair', 'CALIFORNIA', 45000, TO_DATE ('11-JAN-2019','DD-MON-YYYY'));

INSERT INTO SALES_AUTO_LIST VALUES(015, 'Simone Blair', 'OREGON', 38000, TO_DATE ('18-JAN-2019','DD-MON-YYYY'));

COMMIT;

-- 查看 USER_PART_TABLES 中的数据

SELECT

table_name,

partitioning_type,

autolist,

partition_count

FROM

user_part_tables

WHERE

table_name = 'SALES_AUTO_LIST';

TABLE_NAME PARTITIONING_TYPE AUTOLIST PARTITION_COUNT

SALES_AUTO_LIST LIST YES 4

-- 查看 SALES_AUTO_LIST 表中的数据并记下分区名称。

SELECT

table_name,

partition_name,

high_value

FROM

user_tab_partitions

WHERE

table_name = 'SALES_AUTO_LIST';

TABLE_NAME PARTITION_NAME HIGH_VALUE

SALES_AUTO_LIST P_CAL 'CALIFORNIA'

SALES_AUTO_LIST SYS_P1923 'FLORIDA'

SALES_AUTO_LIST SYS_P1924 'MICHIGAN'

SALES_AUTO_LIST SYS_P1925 'OREGON'

-- 按分区名称查看 SALES_AUTO_LIST 表中的数据。

select * from SALES_AUTO_LIST PARTITION(SYS_P1923);

SALESMAN_ID SALESMAN_NAME SALES_STATE SALES_AMOUNT SALES_DATE

21 Mary Smith FLORIDA 41000 21-DEC-18

Task 2: Cleanup

drop table sales_auto_list purge;

Learn More

Automatic List Partitioning Database VLDB and Partitioning Guide

Lab 7: Read Only Partitions

Introduction

我们可以将表、分区和子分区设置为只读状态,以保护数据免受任何用户或触发器的无意 DML 操作。 更新分区设置为只读的分区中的数据将导致错误。 设置为读写的分区将成功更新。 CREATE TABLE 和 ALTER TABLE SQL 语句为分区和子分区提供只读子句。 只读子句的值可以是 READ ONLY 或 READ WRITE。 READ WRITE 是默认值。 任何尝试更新设置为只读的分区或子分区中的数据都会导致错误。

Features

只读属性保证数据的不变性。如果不指定,每个分区和子分区都将继承顶级父级的只读属性允许ADD 和 MODIFY COLUMN,并且不违反现有数据的数据不变性DROP/RENAME/SET UNUSED COLUMN 被禁止禁止DROP [只读] 分区

将上一季度的销售数据设为只读

在金融服务或零售领域,您可以将上一季度的销售数据设置为只读,其余数据可以允许读写 DML 操作。 将分区设置为只读可以作为一种预防措施,以避免意外更新或删除数据。

Task 1: Create Read Only Partitioned Table

我们的测试数据如下:

-- 创建只读分区表

rem simple interval partitioned table with one read only partition

CREATE TABLE ropt (

col1,

col2,

col3

)

NOCOMPRESS

PARTITION BY RANGE (

col1

) INTERVAL ( 10 ) ( PARTITION p1

VALUES LESS THAN ( 1 )

READ ONLY,

PARTITION p2

VALUES LESS THAN ( 11 )

)

AS

SELECT

ROWNUM,

ROWNUM * 10,

rpad('a', ROWNUM, 'b')

FROM

dual

CONNECT BY

level <= 100;

-- 我们为分区 P1 指定了只读,但在其他任何地方都没有指定:

SELECT

table_name,

def_read_only

FROM

user_part_tables

WHERE

table_name = 'ROPT';

TABLE_NAME DEF_READ_ONLY

ROPT NO

SELECT

partition_name,

high_value,

read_only

FROM

user_tab_partitions

WHERE

table_name = 'ROPT';

PARTITION_NAME HIGH_VALUE READ_ONLY

SYS_P1933 31 NO

SYS_P1936 41 NO

SYS_P1939 51 NO

SYS_P1942 61 NO

SYS_P1945 71 NO

SYS_P1948 81 NO

SYS_P1951 91 NO

SYS_P1954 101 NO

P2 11 NO

SYS_P1930 21 NO

P1 1 YES

11 rows selected.

-- 正如预期的那样,在此示例中,我们只有一个分区设置为只读。

-- 这意味着: 表级默认是(并将保持)读写。 只有分区 p1 在显式定义的地方被定义为只读。

-- 您可以更改现有分区的只读/读写属性。

-- 值5属于分区P2

alter table ropt modify partition for (5) read only;

select partition_name, high_value, read_only

from user_tab_partitions

where table_name='ROPT';

PARTITION_NAME HIGH_VALUE READ_ONLY

SYS_P1933 31 NO

SYS_P1936 41 NO

SYS_P1939 51 NO

SYS_P1942 61 NO

SYS_P1945 71 NO

SYS_P1948 81 NO

SYS_P1951 91 NO

SYS_P1954 101 NO

P2 11 YES

SYS_P1930 21 NO

P1 1 YES

11 rows selected.

-- 运行以下查询将报错。

-- 作为分区级别属性,只读可以与其他分区维护操作结合使用。

rem online PMOP will not work when one of the target partitions is read only

alter table ropt split partition for (5) into

(partition pa values less than (7), partition pb read only) online;

ORA-14467: This option cannot be issued with the READ ONLY or READ WRITE clause.

14467. 00000 - "This option cannot be issued with the READ ONLY or READ WRITE clause."

*Document: Yes

*Cause: An attempt was made to issue a READ ONLY or READ WRITE

clause combined with the ONLINE or the INCLUDING ROWS clause.

*Action: Issue the READ ONLY or READ WRITE clause with the ONLINE or

the INCLUDING ROWS clause in separate statements.

-- 当启动 PMOP(分区维护操作)时,只读被认为是一种保证状态。 如果从读写更改为只读,则何时更改状态也是模棱两可的。

rem offline PMOP

alter table ropt split partition for (5) into

(partition pa values less than (7), partition pb read only);

-- 您还可以将整个表设置为只读。 这将更改所有现有分区的状态和表的默认值。 请注意,这与其他属性一致。

rem set everything read only, including the default property

alter table ropt read only;

select partition_name, high_value, read_only

from user_tab_partitions

where table_name='ROPT';

PARTITION_NAME HIGH_VALUE READ_ONLY

SYS_P1968 31 YES

SYS_P1971 41 YES

SYS_P1974 51 YES

SYS_P1977 61 YES

SYS_P1980 71 YES

SYS_P1983 81 YES

SYS_P1986 91 YES

SYS_P1989 101 YES

PA 7 YES

PB 11 YES

SYS_P1965 21 YES

P1 1 YES

12 rows selected.

select partition_name, high_value, read_only, compression

from user_tab_partitions

where table_name='ROPT' and partition_name='PB';

PARTITION_NAME HIGH_VALUE READ_ONLY COMPRESSION

PB 11 YES DISABLED

-- 让我们移动和压缩这个分区:

rem do the move and compress

alter table ropt move partition pb compress for oltp;

-- 只读分区上的分区移动成功,没有引发任何错误。 重新检查分区属性,您现在将看到分区已压缩。

rem partition pb

select partition_name, high_value, read_only, compression

from user_tab_partitions

where table_name='ROPT' and partition_name='PB';

PARTITION_NAME HIGH_VALUE READ_ONLY COMPRESSION

PB 11 YES ENABLED

-- 另一个适用于具有只读分区的表的操作是添加列。

-- 无论新列是否可以为空以及该列是否具有默认值,这样的操作都有效。

rem add a column to the table

alter table ropt add (newcol number default 99);

-- 只读分区上的任何形式的 DML都被禁止:

rem no DML on read only partitions

update ropt set col2=col2 where col1=88;

SQL Error: ORA-12081: update operation not allowed on table "ADMIN"."ROPT"

12081. 00000 - "update operation not allowed on table \"%s\".\"%s\""

*Cause: An attempt was made to update a read-only materialized view.

*Action: No action required. Only Oracle is allowed to update a

read-only materialized view.

-- 删除或截断只读分区 - 因为这在语义上等同于 DELETE FROM 表 WHERE 分区标准。

rem no drop or truncate partition

alter table ropt drop partition for (56);

ORA-12081: update operation not allowed on table "ADMIN"."ROPT"

12081. 00000 - "update operation not allowed on table \"%s\".\"%s\""

*Cause: An attempt was made to update a read-only materialized view.

*Action: No action required. Only Oracle is allowed to update a

read-only materialized view.

alter table ropt drop column col2;

ORA-12081: update operation not allowed on table "ADMIN"."ROPT"

12081. 00000 - "update operation not allowed on table \"%s\".\"%s\""

*Cause: An attempt was made to update a read-only materialized view.

*Action: No action required. Only Oracle is allowed to update a

read-only materialized view.

Task 2: Another Example of Read Only Partitioned Table

-- 创建另一个只读分区表 RDPT2

CREATE TABLE rdpt2 (

oid NUMBER,

odate DATE,

amount NUMBER

)read only

PARTITION BY RANGE (

odate

)

( PARTITION q1_2016

VALUES LESS THAN ( TO_DATE('2016-04-01', 'yyyy-mm-dd') ),

PARTITION q2_2016

VALUES LESS THAN ( TO_DATE('2016-07-01', 'yyyy-mm-dd') ),

PARTITION q3_2016

VALUES LESS THAN ( TO_DATE('2016-10-01', 'yyyy-mm-dd') )

READ WRITE,

PARTITION q4_2016

VALUES LESS THAN ( TO_DATE('2017-01-01', 'yyyy-mm-dd') )

READ WRITE );

-- 只读分区或子分区中的数据不能被修改。

insert into RDPT2 values(1,to_date('2016-01-20','yyyy-mm-dd'),100);

ORA-14466: Data in a read-only partition or subpartition cannot be modified.

-- 将数据插入 RDPT2 表。

insert into RDPT2 values(1,to_date('2016-10-20','yyyy-mm-dd'),100);

insert into RDPT2 values(1,to_date('2016-12-20','yyyy-mm-dd'),100);

commit;

-- 查看 RDPT2 表中的数据

select * from RDPT2;

OID ODATE AMOUNT

1 20-OCT-16 100

1 20-DEC-16 100

Task 3: Cleanup

drop table ropt purge;

drop table RDPT2 purge;

Learn More

Readonly Partition Database VLDB and Partitioning Guide

Lab 8: Multi Column List Partitioning

Introduction

多列列表分区使您可以根据多列的列表值对表进行分区。 与单列列表分区类似,单个分区可以包含包含值列表的集合。 对表的多个列使用 PARTITION BY LIST 子句的表支持多列列表分区。多列列表分区表只能有一个 DEFAULT 分区。

Features

数据组织在多个值的列表中(多列)单个分区可以包含多个值的集合DEFAULT 分区的功能(未指定值的全部内容)非常适合分割不同的值元组,例如(sensor_type,channel,…)

Multi-Column List Partitioning Usecase

多列列表分区的一个很好的例子是在 IoT(物联网)应用程序中分离传感器数据和各种通道数据,例如湿度、温度、气候、压力和空气质量变化。 这些传感器的测量值不断变化。

Task 1: Create Multi Column List Partitioned Table

-- 创建多列表分区表

rem simple multi-column list partitioned table

create table mc (col1 number, col2 number)

partition by list (col1, col2)

(partition p1 values ((1,2),(3,4)),

partition p2 values ((4,4)),

partition p3 values (default));

-- 该表的元数据如下。 您还可以通过查看表元数据中的分区键数来识别多列列表分区。

rem table metadata - number of partition keys

select table_name, partitioning_type, partitioning_key_count

from user_part_tables where table_name='MC';

TABLE_NAME PARTITIONING_TYPE PARTITIONING_KEY_COUNT

MC LIST 2

rem metadata of individual partitions

select partition_name, high_value

from user_tab_partitions where table_name='MC';

PARTITION_NAME HIGH_VALUE

P1 ( 1, 2 ), ( 3, 4 )

P2 ( 4, 4 )

P3 default

-- 现在让我们将一些数据插入到我们之前创建的表中,看看数据实际存储在哪里。

rem insert some sample data

insert into mc values (1,2);

insert into mc values (1,3);

insert into mc values (99,99);

commit;

-- 现在让我们检查一下数据在哪里。 我们将首先使用分区扩展语法专门指向分区 p1。

-- 我们希望看到以 (1,2) 或 (3,4) 作为分区键的唯一有效记录。

rem content of partition p1 using partition extended syntax

select * from mc partition (p1);

COL1 COL2

1 2

-- 通过多列分区,您还可以将分区扩展语法与 FOR () 子句一起使用。 指向完全合格的记录,

-- 这意味着您必须指定完整的分区键标准。

rem content of DEFAULT partition using the partitioned extended syntax PARTITION FOR ()

select * from mc partition for (1,3);

COL1 COL2

1 3

99 99

-- 请注意,DEFAULT 不是一个值,因此如果您尝试使用分区扩展语法将其用作“值”,您将收到错误消息:

rem wrong usage of partition extended syntax: DEFAULT is not a valid partition key value

select * from mc partition for (default);

SQL Error: ORA-00936: missing expression

00936. 00000 - "missing expression"

*Cause:

*Action:

-- 我们来做一个标准的分区维护操作。 您将看到它的行为与任何其他分区方法一样;

-- 唯一的区别是,一个完全限定的分区键现在显然由具有所有分区键列的值的值对组成。

rem simple partition maintenance operation, demonstrating split

alter table mc split partition p3 into (partition p3 values (1,3),partition p4) online;

select * from mc partition (p3);

COL1 COL2

1 3

-- 让我们再次快速检查表的元数据,看看拆分做了什么:

rem partition information for our table

select partition_name, high_value

from user_tab_partitions

where table_name='MC'

order by partition_position;

PARTITION_NAME HIGH_VALUE

P1 ( 1, 2 ), ( 3, 4 )

P2 ( 4, 4 )

P3 ( 1, 3 )

P4 default

-- 新的 DEFAULT 分区包含所有其余记录:

rem content of partition p4 after the split, our new DEFAULT partition

select * from mc partition (p4);

COL1 COL2

99 99

Task 2: Cleanup

drop table mc purge;

Learn More

Partitioning When Creating Tables and Indexes Multi-column list Partitioning

Lab 9: Convert Non Partitioned Table into Partitioned Table

Introduction

Oracle 数据库提供了一种机制来移动一个或多个分区或对分区的物理结构进行其他更改,而不会显着影响 DML 分区的可用性。

将非分区表转换为分区表,并在 ALTER TABLE SQL 语句中添加 MODIFY 子句。 此外,可以指定关键字 ONLINE,在转换过程中启用并发 DML 操作。

Features

索引在整个转换过程中被转换并保持在线。默认索引规则以提供最小或无访问更改行为。如果包含两个维度的任何分区键,则本地索引保持本地全局前缀分区索引将转换为本地分区索引。

Task 1: Convert Non Partitioned Table to Partitioned Table

-- 让我们将非分区表转换为分区表

rem sample nonpartitioned table

create table soon2bpart (col1 number primary key, col2 number, col3 number not null, col4 number);

insert /*+ append */ into soon2bpart

select rownum, mod(rownum,100), mod(rownum,1000), dbms_random.normal from dual connect by level <=10;

commit;

select * from soon2bpart;

COL1 COL2 COL3 COL4

1 1 1 2.95183249761286626288045267412892535679

2 2 2 -0.3321157751312515487155354126518900376464

3 3 3 1.19532912821880444322609891453297017904

4 4 4 -0.9613207629065037519069568974207573135028

5 5 5 0.796832944868301468359541116478474527275

6 6 6 0.2736715791699400993062008565770475691858

7 7 7 0.4041493572017230577716259144266811589354

8 8 8 0.2509196940040299085607229676162665657897

9 9 9 -0.8793344517285506632496471982847182240846

10 10 10 0.6380814394203814168584298025714729117989

10 rows selected.

-- 我们的示例表需要几个索引,所以让我们创建它们

-- 此处所谓的prefix,或有前缀,值得是包含将要分区的列col2

rem create a bunch of different indexes on it

rem some indexes, different shape and type

create index i1_prefix_soon2bpart on soon2bpart(col2);

create index i2_nonprefix_soon2bpart on soon2bpart(col4);

create index i3_prefix_but_ovrd_soon2bpart on soon2bpart(col3, col2);

create index i4_global_part_soon2bpart on soon2bpart(col3) global partition by hash(col3) partitions 4;

create bitmap index i5_bix_soon2bpart on soon2bpart (col2,col3);

-- 让我们看看我们的表的索引元数据,因为它在转换之前就存在。

rem indexes in general

select index_name, index_type, uniqueness, partitioned, status

from user_indexes

where table_name='SOON2BPART'

order by 1;

INDEX_NAME INDEX_TYPE UNIQUENESS PARTITIONED STATUS

I1_PREFIX_SOON2BPART NORMAL NONUNIQUE NO VALID

I2_NONPREFIX_SOON2BPART NORMAL NONUNIQUE NO VALID

I3_PREFIX_BUT_OVRD_SOON2BPART NORMAL NONUNIQUE NO VALID

I4_GLOBAL_PART_SOON2BPART NORMAL NONUNIQUE YES N/A

I5_BIX_SOON2BPART BITMAP NONUNIQUE NO VALID

SYS_C0041653 NORMAL UNIQUE NO VALID

6 rows selected.

rem partitioned index

select index_name, partitioning_type, partition_count, locality

from user_part_indexes

where table_name='SOON2BPART'

order by 1;

INDEX_NAME PARTITIONING_TYPE PARTITION_COUNT LOCALITY

I4_GLOBAL_PART_SOON2BPART HASH 4 GLOBAL

转换不是就地转换:Oracle 分区的关键概念之一是各个分区的数据存储在各个物理段中。 非分区表将数据存储在表中的“任何位置”。 在转换过程中,您将需要额外的空间用于新的表分区和索引段。 转换成功后,注意我们正在进行在线转换。 如果您可以在转换进行时生成第二个会话对我们的表执行 DML,您会体验到您的所有 DML 都将通过而不会被阻止。

rem do an online conversion

rem - only one index will not use default conversion

alter table soon2bpart modify

partition by list (col2) automatic

(partition p1 values (1)) online

update indexes (i3_prefix_but_ovrd_soon2bpart global);

该表现在已转换。 让我们看看表分区元数据。

rem partitioning metadata

select table_name, partitioning_type, partition_count

from user_part_tables where table_name='SOON2BPART';

select partition_name, high_value

from user_tab_partitions where table_name='SOON2BPART'

order by partition_position asc;

TABLE_NAME PARTITIONING_TYPE PARTITION_COUNT

SOON2BPART LIST 10

PARTITION_NAME HIGH_VALUE

P1 1

SYS_P2003 2

SYS_P2004 3

SYS_P2005 4

SYS_P2006 5

SYS_P2007 6

SYS_P2008 7

SYS_P2009 8

SYS_P2010 9

SYS_P2011 10

10 rows selected.

全局分区索引保持不变并保持其形状。 无前缀索引将成为全局非分区索引。 带前缀的索引将成为本地分区索引。 位图索引将成为本地分区索引。 因此,让我们检查索引形状及其状态。

rem indexes general

select index_name, index_type, uniqueness, partitioned, status

from user_indexes

where table_name='SOON2BPART'

order by 1;

INDEX_NAME INDEX_TYPE UNIQUENESS PARTITIONED STATUS

I1_PREFIX_SOON2BPART NORMAL NONUNIQUE YES N/A

I2_NONPREFIX_SOON2BPART NORMAL NONUNIQUE NO VALID

I3_PREFIX_BUT_OVRD_SOON2BPART NORMAL NONUNIQUE NO VALID

I4_GLOBAL_PART_SOON2BPART NORMAL NONUNIQUE YES N/A

I5_BIX_SOON2BPART BITMAP NONUNIQUE YES N/A

SYS_C0041653 NORMAL UNIQUE NO VALID

6 rows selected.

所有索引分区也处于有效状态:

rem status of partitioned index

select ip.index_name, ip.status, count(*) cnt

from user_ind_partitions ip, user_indexes i

where i.index_name=ip.index_name and table_name='SOON2BPART'

group by ip.index_name, ip.status

order by 1;

INDEX_NAME STATUS CNT

I1_PREFIX_SOON2BPART USABLE 10

I4_GLOBAL_PART_SOON2BPART USABLE 4

I5_BIX_SOON2BPART USABLE 10

Task 2: Cleanup

drop table SOON2BPART purge;

Learn More

Automatic List Partitioning Database VLDB and Partitioning Guide

Acknowledgements

本实验作者为Madhusudhan Rao。贡献者为Kevin Lazarz。

整个实验过程很顺畅,感谢作者!

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: