oracle 11g 新增分区

oracle 11g新增了间隔分区、虚拟列分区和引用分区。详细的介绍请查看官方文件:

Creating Partitions

1. 间隔分区



间隔分区是范围分区的一种扩展。在引入间隔分区之前,DBA 需要显式定义每个分区的值范围,随着分区值的增长可用分区会逐渐减少直到没有可使用的分区为止。而间隔分区就是为了解决插入表中的数据超过了所有范围分区时而不能自动创建分区的问题。必须至少创建一个范围分区,范围分区的键值确定范围分区的上限值,超过该上限值数据库服务器自动创建特定间隔的分区。
主要用在可预知的添加小范围分区或固定时间类型的分区添加上。


限制条件如下:
1) 只能指定一个分区键列,并且该键列必须是 NUMBER 或 DATE 类型。
2) 索引表不支持间隔分区。
3) 不能为间隔分区创建域索引
4) 不能为分区指定具体名称,由系统自动生成,格式为:SYS_Pnnn,n为数字。



Date类型测试:
创建时间类型间隔分区时指定NUMTOYMINTERVAL(n,day|month|year)子句确定分区扩展的条件,n为数字,指定按n天/月/年的方式进行分区新增。

CREATE TABLE SH.SALES_INTERVAL
PARTITION BY RANGE (time_id)
INTERVAL (NUMTOYMINTERVAL(1,‘month‘)) STORE IN (tbs1,tbs2,tbs3,tbs4)
(
PARTITION P1 values less than (TO_DATE(‘1-1-2002‘,‘dd-mm-yyyy‘)),
PARTITION P2 values less than (TO_DATE(‘1-1-2003‘,‘dd-mm-yyyy‘)),
PARTITION P3 values less than (TO_DATE(‘1-1-2004‘,‘dd-mm-yyyy‘)))
AS
SELECT *
FROM SH.SALES
WHERE TIME_ID < TO_DATE(‘1-1-2004‘,‘dd-mm-yyyy‘);
select partition_name from user_tab_partitions where table_name=‘SALES_INTERVAL‘;

PARTITION_NAME
---------------------------
P1
P2
P3

insert into sh.SALES_INTERVAL values(101001,4,to_date(‘2005-1-10‘,‘yyyy-mm-dd‘),10,124,100,200);
insert into sh.SALES_INTERVAL values(101002,5,to_date(‘2006-1-14‘,‘yyyy-mm-dd‘),11,125,100,300);

select partition_name from user_tab_partitions where table_name=‘SALES_INTERVAL‘;

PARTITION_NAME
---------------------------
P1
P2
P3
SYS_P121
SYS_P122

Number类型测试:

create table sh.test_interval
(
id number,
name varchar2(20)
)
PARTITION BY RANGE (id)
INTERVAL (100)
(PARTITION P001 values less than(500) ,
PARTITION P002 values less than(1000)
);

insert into sh.test_interval select rownum,‘A‘||rownum from dual connect by level <1201;

select partition_name from user_tab_partitions where table_name=‘TEST_INTERVAL‘;

PARTITION_NAME
------------------------------
P001
P002
SYS_P134
SYS_P135
SYS_P136

select count(*) from TEST_INTERVAL PARTITION(SYS_P134);

  COUNT(*)
----------
       100

select count(*) from TEST_INTERVAL PARTITION(SYS_P135);

  COUNT(*)
----------
       100



合并分区:
需要注意,分区一定要连续,否则报ORA-14274

alter table SALES_INTERVAL merge partitions for(to_date(‘2005-10-10‘,‘yyyy-mm-dd‘)),for(to_date(‘2005-11-10‘,‘yyyy-mm-dd‘))  into partition SYS_P137



强制创建:

LOCK TABLE SALES_INTERVAL PARTITION FOR(to_date(‘2008-1-14‘,‘yyyy-mm-dd‘)) IN SHARE MODE;

范围分区转换为间隔分区:

alter table TEST drop partition p_max;
alter table TEST set interval(numtodsinterval(1,‘DAY‘))
alter table TEST set STORE IN (P1,P2,P3,P4)

2. 基于虚拟列的分区



如果某个表的列值是通过计算函数或表达式得到的,则这些列就称为虚拟列。可以在 CREATE 或 ALTER 表操作过程中指定这些列。虚拟列与其它实际表列共享相同的 SQL 名称空间,并与对其进行描述的基础表达式的数据类型相一致。可像其它表列一样在查询 中使用这些列,因此可在 SQL 语句中提供简单、优美且一致的访问表达式机制。
虚拟列的值实际上并未存储在磁盘上的表行中,而是根据需要进行计算。描述虚拟列的函数或表达式应是明确且唯一的,即相同的输入值集应返回相同的输出值。
可以像使用任何其它表列一样使用虚拟列。可对虚拟列进行索引,可在查询、DML 和 DDL 语句中使用它们。可在虚拟列上对表和索引进行分区,甚至可以收集它们的统计信息。 可使用虚拟列分区对表的虚拟列上定义的键列进行分区。对逻辑分区对象的业务要求经常 与现有列不一一对应。随着 Oracle Database 11g 的推出,分区功能得到了增强,可以在虚 拟列上定义分区策略,因而可以更全面地满足业务要求。
如果分区键上的谓词属于以下类型之一,则将对虚拟列分区键执行分区修剪:
? 等式或 Like
? 列表
? 范围
? 扩展分区名称



创建测试表

CREATE TABLE employees
(employee_id number(6) not null, first_name varchar2(30),
last_name varchar2(40) not null, emailvarchar2(25),
phone_number varchar2(20), hire_date date not null,
job_id varchar2(10) not null, salary number(8,2),
commission_pct number(2,2), manager_id number(6),
department_id number(4),
total_compensation as (salary *( 1+commission_pct))
)
PARTITION BY RANGE (total_compensation)
(
PARTITION p1 VALUES LESS THAN (50000),
PARTITION p2 VALUES LESS THAN (100000),
PARTITION p3 VALUES LESS THAN (150000),
PARTITION p4 VALUES LESS THAN (MAXVALUE)
);

插入数据:

insert into employees_inv
(EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
EMAIL,
PHONE_NUMBER,
HIRE_DATE,
JOB_ID,
SALARY,
COMMISSION_PCT,
MANAGER_ID,
DEPARTMENT_ID)
select EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
EMAIL,
PHONE_NUMBER,
HIRE_DATE,
JOB_ID,
SALARY,
COMMISSION_PCT,
MANAGER_ID,
DEPARTMENT_ID
from employees
where COMMISSION_PCT is not null
and rownum < 10;

确认:

select EMPLOYEE_ID,SALARY,COMMISSION_PCT,TOTAL_COMPENSATION from employees_inv;

EMPLOYEE_ID     SALARY COMMISSION_PCT TOTAL_COMPENSATION
---------- ---------- -------------- ------------------
14000             .4              19600
13500             .3              17550
12000             .3              15600
11000             .3              14300
10500             .2              12600
10000             .3              13000
9500            .25              11875
9000            .25              11250
8000             .2               9600

3. 引用分区



引用分区通过在create table中指定PARTITION BY REFERENCE子句实现分区,不需要指定分区列,分区信息继承自父表且自动维护。

创建测试表:

 CREATE TABLE orders
    ( order_id           NUMBER(12),
      order_date         date,
      order_mode         VARCHAR2(8),
      customer_id        NUMBER(6),
      order_status       NUMBER(2),
      order_total        NUMBER(8,2),
      sales_rep_id       NUMBER(6),
      promotion_id       NUMBER(6),
      CONSTRAINT orders_pk PRIMARY KEY(order_id)
    )
  PARTITION BY RANGE(order_date)
    ( PARTITION Q1_2005 VALUES LESS THAN (TO_DATE(‘01-APR-2005‘,‘DD-MON-YYYY‘)),
      PARTITION Q2_2005 VALUES LESS THAN (TO_DATE(‘01-JUL-2005‘,‘DD-MON-YYYY‘)),
      PARTITION Q3_2005 VALUES LESS THAN (TO_DATE(‘01-OCT-2005‘,‘DD-MON-YYYY‘)),
      PARTITION Q4_2005 VALUES LESS THAN (TO_DATE(‘01-JAN-2006‘,‘DD-MON-YYYY‘))
    );



创建测试子表:

CREATE TABLE order_items
    ( order_id           NUMBER(12) NOT NULL,
      line_item_id       NUMBER(3)  NOT NULL,
      product_id         NUMBER(6)  NOT NULL,
      unit_price         NUMBER(8,2),
      quantity           NUMBER(8),
      CONSTRAINT order_items_fk
      FOREIGN KEY(order_id) REFERENCES orders(order_id)
    )
    PARTITION BY REFERENCE(order_items_fk);



确认分区:

 select table_name,partition_name from user_tab_partitions where table_name like ‘%ORDER%‘  order by 1,2;

TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS                         Q1_2005
ORDERS                         Q2_2005
ORDERS                         Q3_2005
ORDERS                         Q4_2005
ORDER_ITEMS                    Q1_2005
ORDER_ITEMS                    Q2_2005
ORDER_ITEMS                    Q3_2005
ORDER_ITEMS                    Q4_2005

父表添加分区

alter table orders add partition Q1_2006 values less than (TO_DATE(‘01-APR-2006‘,‘DD-MON-YYYY‘));

Table altered.

[email protected]> select table_name,partition_name from user_tab_partitions where table_name like ‘%ORDER%‘  order by 1,2;

TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS                         Q1_2005
ORDERS                         Q1_2006
ORDERS                         Q2_2005
ORDERS                         Q3_2005
ORDERS                         Q4_2005
ORDER_ITEMS                    Q1_2005
ORDER_ITEMS                    Q1_2006
ORDER_ITEMS                    Q2_2005
ORDER_ITEMS                    Q3_2005
ORDER_ITEMS                    Q4_2005



子表添加分区

[email protected]> alter table ORDER_ITEMS add partition Q2_2006 values less than (TO_DATE(‘01-JUL-2006‘,‘DD-MON-YYYY‘));
alter table ORDER_ITEMS add partition Q2_2006 values less than (TO_DATE(‘01-JUL-2006‘,‘DD-MON-YYYY‘))
            *
ERROR at line 1:
ORA-14650: operation not supported for reference-partitioned tables

其他说明:

  1. 如果未显式指定表空间,则引用分区表的分区将与父表的对应分区保存在同一位置。
  2. 与其它分区表一样,可以指定对象级的默认属性和覆盖对象级默认值的分区描述符。
  3. 不能禁用引用分区表的外键约束条件。
  4. 不允许添加或删除引用分区表的分区。但是,在父表上执行分区维护操作将自动级联到子表。

原文地址:https://blog.51cto.com/hunt1574/2419378

时间: 2024-08-01 10:18:27

oracle 11g 新增分区的相关文章

Oracle 11g 间隔分区(INTERVAL)批量规范命名

友情提示:请在业务空闲是操作.为什么呢? --Oracle 11g 间隔分区(INTERVAL)重命名,批量生成rename分区脚本 set linesize  180 set serverout on declare   v_table_owner          varchar2(100) :=  'OP%';   v_table_name_day_p     varchar2(100);   v_table_name_month_p    varchar2(100);   v_print

Oracle 11g新增not null的字段比10g快--新特性

在11g之前添加一个not null的字段很慢.在11g之后就很快了.我们先做一个測试,然后探究下原理. SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi PL/SQL Release 10.2.0.1.0 - Pr

oracle 11G 间隔分区

在项目数据库设计过程中由于单表的数据量非常庞大,需要对表进行分区处理.由于表中的数据是历史交易,故按月分区,提升查询和管理. 由于之前对于表分区了解不多,为了实现上述功能查了很多资料,一开始的方向是通过Crontab调用Shell脚本来按月自动创建分区,或者使用 Oracle的Job调用存储过程来自动创建分区.在研究上述两套方案的过程中,无意发现Oracle11g有间隔分区功能,对于使用Range分区的可 以按年,月,日来自动生成分区.语法如下: [sql] view plaincopy CRE

Oracle 11g 间隔分区,导出报错 EXP-00006

一.描述前天系统对个别表进行分区,采用间隔分区,第二天凌晨exp备份间隔分区表报错,报错关键字EXP-00006 二.现象 When exporting a composite. interval, or system partitioned table using conventional export utility, it fails with EXP-6 and EXP-0 errors: EXP-00006: internal inconsistency errorEXP-00000:

oracle 11g不能导出空表的解决方法

在oracle 11g r2中,发现传统的exp居然不能导出空的表,然后查询一下, 发现需要如下的步骤去搞,笔记之. oracle 11g 新增了一个参数:deferred_segment_creation,含义是段延迟创建,默认是true.具体是什么意思呢? 如果这个参数设置为true,你新建了一个表T1,并且没有向其中插入数据,那么这个表不会立即分配extent,也就是不占数据空间,只有当你insert数据后才分配空间.这样可以节省少量的空间. 解决办法 1 设置deferred_segme

工作之:oracle 11g deferred_segment_creation段延迟创建(转载他人)

oracle 11g 新增了一个参数:deferred_segment_creation,含义是段延迟创建,默认是true.具体是什么意思呢? 如果这个参数设置为true,你新建了一个表T1,并且没有向其中插入数据,那么这个表不会立即分配extent,也就是不占数据空间,只有当你insert数据后才分配空间.这样可以节省少量的空间. 一.问题提出:这带来一个问题:如果你通过EXP命令来导出整个用户时,你会发现所有没有数据的表都导不出来.如何解决这个问题呢? 二.问题分析: 1.既然新建的表没有分

oracle 11g导出少了空表,原因分析

oracle 11g导出少了空表 使用exp命令的时候,会出现少表的情况,是因为在11g版本中如果一个表里面是空的,为了节省空间,默认是不会给这个表分配空间的,在导出的时候也就不会将空表导出的,自然导入到另一个库里的时候会出现少表的情况.但缺少的表虽然里面没有数据,但有时候还是会影响到应用程序的执行,所以得把所有表都得导出来. 所以在正常导出表时,请一定要注意. 原因分析: 由于oracle 11g新增了一个参数: "deferred_segment_creation" "段

Oracle 11g实时SQL监控 v$sql_monitor

Oracle 11g实时SQL监控: 前面提到,在Oracle Database 11g中,v$session视图增加了一些新的字段,这其中包括SQL_EXEC_START和SQL_EXEC_ID, 这两个字段实际上代表了Oracle 11g的一个新特性:实时的SQL监控(Real Time SQL Monitoring). 在Oracle 11g之前的版本,长时间运行的SQL可以通过监控v$session_longops来观察,当某个操作执行时间超过6秒, 就会被记录在v$session_lo

Oracle 11g 新特性:自动创建分区(Interval Partition)

分区(Partition)一直是Oracle数据库引以为傲的一项技术,正是分区的存在让Oracle高效的处理海量数据成为可能,在Oracle 11g中,分区技术在易用性和可扩展性上再次得到了增强.在10g的Oracle版本中,要对分区表做调整,尤其是对RANGE分区添加新的分区都需要DBA手动定期添加,或都使用存储过程进行管理.在11G的版本中的Interval Partition不再需要DBA去干预新分区的添加,Oracle会自动去执行这样的操作,减少了DBA的工作量.Interval Par