扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
在Oracle10g中,没有定义间隔分区,只能通过范围分区实现间隔分区功能,如果要实现自动创建分区,只能通过创建JOB或者scheduler来实现;而在11g中,Oracle直接提供了间隔分区功能,大大简化了间隔分区的实现。
创新互联公司是网站建设技术企业,为成都企业提供专业的成都网站设计、做网站,网站设计,网站制作,网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制适合企业的网站。10多年品质,值得信赖!
----注:oracle11g虽然可以自动分区,但是分区的名字不能自定义,对于需要定时删除分区时没法处理,不如通过时间范围来手工分区。详见
create table HIP_LOG_NODE_Part
(
ID VARCHAR2(32) not null,
RECORD_TIME DATE
)tablespace TB_HIP_LOG_NODE
PARTITION BY RANGE (RECORD_TIME) interval (numtoyminterval(1, 'month'))
STORE IN (TB_HIP_LOG_NODE)
(
partition hip_log_node_partition values less than (to_date('2019-08-01 00:00','yyyy-MM-dd HH24:mi')) tablespace TB_HIP_LOG_NODE
);
1、Oracle11g有间隔分区功能,对于使用Range分区的可以按年,月,日来自动生成分区。
2、2019-08-01前的数据(包含8月份的数据)会放入hip_log_node_partition 分区,8月1日后的数据每月只要有数据,就会自动创建一个分区。也就是从9月开始,开始新建分区。
3、interval函数--将数值按标准换算为日期
numtodsinterval、numtodsinterval函数,将数字转成年月,时分秒
详见:
4、查看表分区 select table_name,partition_name from user_tab_partitions where table_name='INTERVAL_SALES';
5、插入数据再次查看分区,详见:
6、修改分区、合并分区、拆分分区,详见 :
7、创建索引(分区索引、全局索引) :
非分区字段创建主键,则创建主键local索引时必须加上分区字段
ALTER TABLE TEST ADD CONSTRAINT PK_TEST PRIMARY KEY (主键字段,分区字段) USING INDEX LOCAL;
8、oracle 10g创建表分区
9、删除
1.不保留,直接删除:
alter table table_name drop/truncate partition partition_name;
具体用drop还是truncate,得你自己衡量,drop的话原来的分区和数据直接就没有了,truncate的话,只是数据没有了,分区还在。
其实不需要拆分表,分区就可以,还是原来的表名,只是将原来的表分成了若干的分区,这样能起到分表的效果,还不用分成很多的表。
比如你原来的表的名字是A,那么将该表改为A1,然后从新建立一个分区表A,分区的依据是班级,也就是list分区,也就是一般意义上的列表分区表。
然后再将A1的数据插入新A表就可以了。
至于分区表的建立方式,往上很多,可以自行查找。
这样操作查询的语句不需要变,只是在不跨分区查询的情况下,相当于分成了若干张表去查询。比如查询1班的成绩,那么就是在1班的分区内,不会有2班的问题,就相当于你用一个指头就能解决问题,不会动用这个手一样。
如果分表的话,那么假设有12个班,那么就要建立12张表,这样的话,语句就要写12次,冗余太大了。
日期为什么不用范围分区??
spilt分区都是用于范围分区的,你这样的列表分区,添加删除分区就行了
将一个分区拆成两个:
ALTER TABLE tab_2
SPLIT PARTITION pm AT (to_date('20120310','yyyymmdd'))
INTO (PARTITION p2,
PARTITION pm)
在大型的企业应用或企业级的数据库应用中 要处理的数据量通常可以达到几十到几百GB 有的甚至可以到TB级 虽然存储介质和数据处理技术的发展也很快 但是仍然不能满足用户的需求 为了使用户的大量的数据在读写操作和查询中速度更快 Oracle提供了对表和索引进行分区的技术 以改善大型应用系统的性能
使用分区的优点
·增强可用性 如果表的某个分区出现故障 表在其他分区的数据仍然可用
·维护方便 如果表的某个分区出现故障 需要修复数据 只修复该分区即可
·均衡I/O 可以把不同的分区映射到磁盘以平衡I/O 改善整个系统性能
·改善查询性能 对分区对象的查询可以仅搜索自己关心的分区 提高检索速度
Oracle数据库提供对表或索引的分区方法有三种
·范围分区
·Hash分区(散列分区)
·复合分区
下面将以实例的方式分别对这三种分区方法来说明分区表的使用 为了测试方便 我们先建三个表空间
以下为引用的内容
create tablespace dinya_space
datafile /test/demo/oracle/demodata/dinya dnf size M
create tablespace dinya_space
datafile /test/demo/oracle/demodata/dinya dnf size M
create tablespace dinya_space
datafile /test/demo/oracle/demodata/dinya dnf size M
分区表的创建
范围分区
范围分区就是对数据表中的某个值的范围进行分区 根据某个值的范围 决定将该数据存储在哪个分区上 如根据序号分区 根据业务记录的创建日期进行分区等
需求描述 有一个物料交易表 表名 material_transactions 该表将来可能有千万级的数据记录数 要求在建该表的时候使用分区表 这时候我们可以使用序号分区三个区 每个区中预计存储三千万的数据 也可以使用日期分区 如每五年的数据存储在一个分区上
根据交易记录的序号分区建表 以下为引用的内容
SQL create table dinya_test
(
transaction_id number primary key
item_id number( ) not null
item_description varchar ( )
transaction_date date not null
)
partition by range (transaction_id)
(
partition part_ values less than( ) tablespace dinya_space
partition part_ values less than( ) tablespace dinya_space
partition part_ values less than(maxvalue) tablespace dinya_space
);
Table created
建表成功 根据交易的序号 交易ID在三千万以下的记录将存储在第一个表空间dinya_space 中 分区名为:par_ 在三千万到六千万之间的记录存储在第二个表空间
dinya_space 中 分区名为 par_ 而交易ID在六千万以上的记录存储在第三个表空间dinya_space 中 分区名为par_
根据交易日期分区建表
以下为引用的内容
SQL create table dinya_test
(
transaction_id number primary key
item_id number( ) not null
item_description varchar ( )
transaction_date date not null
)
partition by range (transaction_date)
(
partition part_ values less than(to_date( yyyy mm dd ))
tablespace dinya_space
partition part_ values less than(to_date( yyyy mm dd ))
tablespace dinya_space
partition part_ values less than(maxvalue) tablespace dinya_space
);
Table created
这样我们就分别建了以交易序号和交易日期来分区的分区表 每次插入数据的时候 系统将根据指定的字段的值来自动将记录存储到制定的分区(表空间)中
当然 我们还可以根据需求 使用两个字段的范围分布来分区 如partition
by range ( transaction_id transaction_date)
分区条件中的值也做相应的改变 请读者自行测试
Hash分区(散列分区)
散列分区为通过指定分区编号来均匀分布数据的一种分区类型 因为通过在I/O设备上进行散列分区 使得这些分区大小一致 如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中
以下为引用的内容
SQL create table dinya_test
(
transaction_id number primary key
item_id number( ) not null
item_description varchar ( )
transaction_date date
)
partition by hash(transaction_id)
(
partition part_ tablespace dinya_space
partition part_ tablespace dinya_space
partition part_ tablespace dinya_space
);
Table created
建表成功 此时插入数据 系统将按transaction_id将记录散列地插入三个分区中 这里也就是三个不同的表空间中
复合分区
有时候我们需要根据范围分区后 每个分区内的数据再散列地分布在几个表空间中 这样我们就要使用复合分区 复合分区是先使用范围分区 然后在每个分区内再使用散列分区的一种分区方法 如将物料交易的记录按时间分区 然后每个分区中的数据分三个子分区 将数据散列地存储在三个指定的表空间中
以下为引用的内容
SQL create table dinya_test
(
transaction_id number primary key
item_id number( ) not null
item_description varchar ( )
transaction_date date
)
partition by range(transaction_date)subpartition by hash(transaction_id)
subpartitions store in (dinya_space dinya_space dinya_space )
(
partition part_ values less than(to_date( yyyy mm dd ))
partition part_ values less than(to_date( yyyy mm dd ))
partition part_ values less than(maxvalue)
);
Table created
该例中 先是根据交易日期进行范围分区 然后根据交易的ID将记录散列地存储在三个表空间中
分区表操作
以上了解了三种分区表的建表方法 下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作
插入记录
以下为引用的内容
SQL insert into dinya_test values( BOOKS sysdate);
row created
SQL insert into dinya_test values( BOOKS sysdate+ );
row created
SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));
row created
SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));
row created
SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));
row created
SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));
row created
SQL mit;
Commit plete
SQL
按上面的建表结果 年前的数据将存储在第一个分区part_ 上 而 年到 年的交易数据将存储在第二个分区part_ 上 年以后的记录存储在第三个分区part_ 上
查询分区表记录 以下为引用的内容
SQL select * from dinya_test partition(part_ );
TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE
BOOKS : :
BOOKS : :
SQL
SQL select * from dinya_test partition(part_ );
TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE
BOOKS
BOOKS
SQL
SQL select * from dinya_test partition(part_ );
TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE
BOOKS
BOOKS
SQL
从查询的结果可以看出 插入的数据已经根据交易时间范围存储在不同的分区中 这里是指定了分区的查询 当然也可以不指定分区 直接执行select * from dinya_test查询全部记录
在也检索的数据量很大的时候 指定分区会大大提高检索速度
更新分区表的记录
以下为引用的内容
SQL update dinya_test partition(part_ ) t set em_description= DESK where
t transaction_id= ;
row updated
SQL mit;
Commit plete
SQL
这里将第一个分区中的交易ID= 的记录中的item_description字段更新为 DESK 可以看到已经成功更新了一条记录 但是当更新的时候指定了分区 而根据查询的记录不在该分区中时 将不会更新数据 请看下面的例子 以下为引用的内容
SQL update dinya_test partition(part_ ) t set em_description= DESK where
t transaction_id= ;
rows updated
SQL mit;
Commit plete
SQL
指定了在第一个分区中更新记录 但是条件中限制交易ID为 而查询全表 交易ID为 的记录在第三个分区中 这样该条语句将不会更新记录
删除分区表记录
以下为引用的内容
SQL delete from dinya_test partition(part_ ) t where t transaction_id= ;
row deleted
SQL mit;
Commit plete
SQL
上面例子删除了第二个分区part_ 中的交易记录ID为 的一条记录 和更新数据相同 如果指定了分区 而条件中的数据又不在该分区中时 将不会删除任何数据
分区表索引的使用
分区表和一般表一样可以建立索引 分区表可以创建局部索引和全局索引 当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引
局部索引分区的建立
以下为引用的内容
SQL create index dinya_idx_t on dinya_test(item_id)
local
(
partition idx_ tablespace dinya_space
partition idx_ tablespace dinya_space
partition idx_ tablespace dinya_space
);
Index created
SQL
看查询的执行计划 从下面的执行计划可以看出 系统已经使用了索引
以下为引用的内容
SQL select * from dinya_test partition(part_ ) t where em_id= ;
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )
TABLE ACCESS (BY LOCAL INDEX ROWID) OF DINYA_TEST (Cost=
Card= Bytes= )
INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=
Card= )
Statistics
recursive calls
db block gets
consistent gets
physical reads
redo size
bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed
SQL
全局索引分区的建立
全局索引建立时global 子句允许指定索引的范围值 这个范围值为索引字段的范围值
以下为引用的内容
SQL create index dinya_idx_t on dinya_test(item_id)
global partition by range(item_id)
(
partition idx_ values less than ( ) tablespace dinya_space
partition idx_ values less than ( ) tablespace dinya_space
partition idx_ values less than (maxvalue) tablespace dinya_space
);
Index created
SQL
本例中对表的item_id字段建立索引分区 当然也可以不指定索引分区名直接对整个表建立索引 如
以下为引用的内容
SQL create index dinya_idx_t on dinya_test(item_id);
Index created
SQL
同样的 对全局索引根据执行计划可以看出索引已经可以使用
以下为引用的内容
SQL select * from dinya_test t where em_id= ;
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )
TABLE ACCESS (BY GLOBAL INDEX ROWID) OF DINYA_TEST (Cost
= Card= Bytes= )
INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=
Card= )
Statistics
recursive calls
db block gets
consistent gets
physical reads
redo size
bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed
SQL
分区表的维护
了解了分区表的建立 索引的建立 表和索引的使用后 在应用的还要经常对分区进行维护和管理 日常维护和管理的内容包括 增加一个分区 合并一个分区及删除分区等等 下面以范围分区为例说明增加 合并 删除分区的一般操作
增加一个分区:
以下为引用的内容
SQL alter table dinya_test
add partition part_ values less than(to_date( yyyy mm dd ))
tablespace dinya_spa
ce ;
Table altered
SQL
增加一个分区的时候 增加的分区的条件必须大于现有分区的最大值 否则系统将提示ORA partition bound must collate higher than that of the last partition 错误
合并一个分区
以下为引用的内容
SQL alter table dinya_test merge partitions part_ part_ into partition part_ ;
Table altered
SQL
在本例中将原有的表的part_ 分区和part_ 分区进行了合并 合并后的分区为part_ 如果在合并的时候把合并后的分区定为part_ 的时候 系统将提示ORA cannot reuse lower bound partition as resulting partition 错误
删除分区
以下为引用的内容
SQL alter table dinya_test drop partition part_ ;
Table altered
SQL
删除分区表的一个分区后 查询该表的数据时显示 该分区中的数据已全部丢失 所以执行删除分区动作时要慎重 确保先备份数据后再执行 或将分区合并
总结
lishixinzhi/Article/program/Oracle/201311/17329
管理分区表:拆分、添加与交换分区
skyin_1603
2016-12-05 17:00:41
Oracle
原创
这里说的拆分分区,只对maxvalue分区的分区表来说的,实质也是添加分区。
以下是测试过程:
----拆分分区 添加分区与交换分区:
---拆分分区:(拆分分区的前提条件是有一个maxvalue分区)
suxing@PRODSET LINES 120
suxing@PRODCOL TABLE_NAME FOR A15
suxing@PRODCOL PARTITION_NAME FOR A15
suxing@PRODCOL TABLESPACE_NAME FOR A30
suxing@PRODSELECT TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME
2 FROM USER_TAB_PARTITIONS;
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
--------------- --------------- ------------------------------
P_TEST P_10 MYSPACE
P_TEST P_20 USERS
P_TEST P_30 MYSPACE
P_TEST P_40 USERS
---查看表中分区p_40的数据记录:
suxing@PRODselect * from p_test partition (p_40);
ID NAME CREATED
---------- ---------- -------------------
44 susu 2016-12-05 09:53:59
55 susu 2016-12-05 09:54:06
---尝试拆分分区p_40:
suxing@PRODalter table p_test split partition p_40 at(50)
2 into (partition p_400,partition p_max);
Table altered.
#分区p_40已经拆分完成。
---再次查看分区情况:
suxing@PRODSELECT TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME
2 FROM USER_TAB_PARTITIONS;
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
--------------- --------------- ------------------------------
P_TEST P_400 USERS
P_TEST P_10 MYSPACE
P_TEST P_20 USERS
P_TEST P_30 MYSPACE
P_TEST P_MAX USERS
#分区已经成功。
---查看新分两个分区的记录:
suxing@PRODselect * from p_test partition (p_400);
ID NAME CREATED
---------- ---------- -------------------
44 susu 2016-12-05 09:53:59
suxing@PRODselect * from p_test partition (p_MAX);
ID NAME CREATED
---------- ---------- -------------------
55 susu 2016-12-05 09:54:06
#拆分前,最大的分区共有两条数据记录,拆分后,两个新分区各得一条记录。
#拆分分区的前提条件是分区表有maxvalue分区,如果该分区表的(除自动分区表)没有该分区的,只能使用
alter table table_name add partition partition_name 来添加新分区。
而有maxvalue分区的一般通过拆分方式添加新分区。
---尝试直接add方式给没有maxvalue分区的分区表添加新分区:
suxing@PRODalter table p_test add partition p_500
2 values less than (60) tablespace myspace;
alter table p_test add partition p_500
*
ERROR at line 1:
ORA-14074: partition bound must collate higher than that of the last partition
#报错,不能添加新分区。
----交换分区:
---创建另外的普通测试表:
suxing@PRODcreate table pp_test(
2 id number(2),
3 name varchar2(10),
4 created date);
Table created.
---往测试表pp_test插入3条记录:
insert into pp_test values(41,'susu',sysdate);
insert into pp_test values(42,'susu',sysdate);
insert into pp_test values(43,'susu',sysdate);
suxing@PRODcommit;
---查看测试表pp_test的数据记录:
suxing@PRODselect * from pp_test;
ID NAME CREATED
---------- ---------- -------------------
41 susu 2016-12-05 16:26:19
42 susu 2016-12-05 16:26:48
43 susu 2016-12-05 16:26:50
---查看分区表分区p_400的记录:
suxing@PRODselect * from p_test partition (p_400);
ID NAME CREATED
---------- ---------- -------------------
44 susu 2016-12-05 09:53:59
---进行分区交换:
suxing@PRODalter table p_test exchange partition p_400 with table pp_test;
Table altered.
#交换完成。
---再次查看测试表pp_test记录:
suxing@PRODselect * from pp_test;
ID NAME CREATED
---------- ---------- -------------------
44 susu 2016-12-05 09:53:59
---再次查看分区表分区p_400的记录:
suxing@PRODselect * from p_test partition (p_400);
ID NAME CREATED
---------- ---------- -------------------
41 susu 2016-12-05 16:26:19
42 susu 2016-12-05 16:26:48
43 susu 2016-12-05 16:26:50
#分区交换成功。
分区表管理:合并分区
vi编辑器相关命令
ITPUB论坛 | chinaunix博客 | chinaunix论坛
北京皓辰网域网络信息技术有限公司. 版权所有
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流