概述
此实验关于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。
整个实验过程很顺畅,感谢作者!
推荐阅读
发表评论