首页 > 数据库 > Oracle > 分区表2-普通表转分区表方法
将普通表转换成分区表有4种方法:
具体参考:
2.1
SQL> select count(*) from dba;
----------
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select time_fee from dba where rownum<5;
TIME_FEE
-------------------
2011-02-17 19:29:09
2011-02-17 19:29:15
2011-02-17 19:29:18
2011-02-17 19:29:20
SQL>
2.1.1
CREATE TABLE intervaldave
PARTITION BY RANGE (time_fee)
AS
SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALDAVE';
TABLE_NAME
------------------------------ ------------------------------
INTERVALDAVE
INTERVALDAVE
INTERVALDAVE
INTERVALDAVE
INTERVALDAVE
INTERVALDAVE
INTERVALDAVE
2.1.2
sql> create table pdba (id, time) partition by range (time)
表已创建。
SQL> select table_name,partition_name from user_tab_partitions where table_name='PDBA';
TABLE_NAME
------------------------------ ------------------------------
PDBA
PDBA
PDBA
PDBA
sql> select count(*) from pdba partition (p1);
----------
sql> select count(*) from pdba partition (p2);
----------
sql> select count(*) from pdba partition (p3);
----------
sql> select count(*) from pdba partition (p4);
----------
sql>
现在分区表已经建好了,但是表名不一样,需要用rename对表重命名一下:
SQL> rename dba to dba_old;
表已重命名。
SQL> rename pdba to dba;
表已重命名。
SQL> select table_name,partition_name from user_tab_partitions where table_name='DBA';
TABLE_NAME
------------------------------ ------------------------------
DBA
DBA
DBA
DBA
2.2 . 交换分区:Partition exchange method
交换分区的操作步骤如下:
创建分区表:
sql> create table p_dba
表已创建。
注意:我这里只创建了2个分区,没有创建存放其他数据的分区。
创建2个分别对应分区的基表:
SQL> CREATE TABLE dba_p1 as SELECT
id,time_fee FROM dba_old WHERE
表已创建。
SQL> CREATE TABLE dba_p2 as SELECT
id,time_fee FROM dba_old WHERE
表已创建。
SQL> select count(*) from dba_p1;
----------
SQL> select count(*) from dba_p2;
----------
SQL>
讲2个基表与2个分区进行交换:
SQL> alter table p_dba exchange partition p1 with table dba_p1;
表已更改。
SQL> alter table p_dba exchange partition p2 with table dba_p2;
表已更改。
查询2个分区:
SQL> select count(*) from p_dba partition(p1);
----------
SQL> select count(*) from p_dba partition(p2);
----------
注意:数据和之前的基表一致。
查询原来的2个基表:
SQL> select count(*) from dba_p2;
----------
SQL> select count(*) from dba_p1;
----------
注意: 2个基表的数据变成成0。
SQL> insert into p_dba values(999999,to_date('2012-12-29','yyyy-mm-dd'));
insert into p_dba values(999999,to_date('2012-12-29','yyyy-mm-dd'))
第 1 行出现错误:
ORA-14400: 插入的分区关键字未映射到任何分区
SQL> insert into p_dba values(999999,to_date('2009-12-29','yyyy-mm-dd'));
已创建 1 行。
SQL> select * from p_dba where id=999999;
---------- --------------
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select * from p_dba where id=999999;
---------- -------------------
SQL>
2.3 . 使用在线重定义:DBMS_REDEFINITION
关于DBMS_REDEFINITION的介绍,参考官方连接:
关于用在线重定义创建分区表,参考:
这个功能只在9.2.0.4以后的版本才有,在线重定义表具有以下功能:
使用在线重定义的一些限制条件:
(1) There must be enough space to hold two copies of the table.
(2) Primary key columns cannot be modified.
(3) Tables must have primary keys.
(4) Redefinition must be done within the same schema.
(5) New columns added cannot be made NOT NULL until after the redefinition operation.
(6) Tables cannot contain LONGs, BFILEs or User Defined Types.
(7) Clustered tables cannot be redefined.
(8) Tables in the SYS or SYSTEM schema cannot be redefined.
(9) Tables with materialized view logs or materialized views defined on them cannot be redefined.
(10) Horizontal sub setting of data cannot be performed during the redefinition.
在Oracle 10.2.0.4和11.1.0.7 版本下,在线重定义可能会遇到如下bug:
在线重定义的大致操作流程如下:
下面看一个示例:
1. 创建基本表和索引
sql> conn icd/icd;
已连接。
sql> create table unpar_table (
表已创建。
sql> insert into unpar_table select rownum, created from dba_objects;
已创建72288行。
sql> create index create_date_ind on unpar_table(create_date);
索引已创建。
sql> commit;
提交完成。
2. 收集表的统计信息
sql> exec dbms_stats.gather_table_stats('icd', 'unpar_table', cascade => true);
pl/sql 过程已成功完成。
3. 创建临时分区表
sql> create
table
表已创建。
4. 进行重定义操作
4.1 检查重定义的合理性
sql> exec dbms_redefinition.can_redef_table('icd', 'unpar_table');
pl/sql 过程已成功完成。
4.2 如果4.1 没有问题,开始重定义,这个过程可能要等一会。
这里要注意:如果分区表和原表列名相同,可以用如下方式进行:
SQL> BEGIN
DBMS_REDEFINITION.start_redef_table(
uname
=> 'ICD',
orig_table => 'unpar_table',
int_table => 'par_table');
END;
/
SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(
'ICD',
'unpar_table',
'par_table',
'ID ID, create_date TIME', -- 在这里指定新的映射关系
DBMS_REDEFINITION.CONS_USE_PK);
这一步操作结束后,数据就已经同步到这个临时的分区表里来了。
4.3 同步新表,这是可选的操作
SQL> BEGIN
PL/SQL 过程已成功完成。
4.4 创建索引,在线重定义只重定义数据,索引还需要单独建立。
sql> create index create_date_ind2 on par_table(time);
索引已创建。
4.5 收集新表的统计信息
sql> exec dbms_stats.gather_table_stats('icd', 'par_table', cascade => true);
pl/sql 过程已成功完成。
4.6 结束重定义
SQL> BEGIN
PL/SQL 过程已成功完成。
结束重定义的意义:
5. 删除临时表
SQL> DROP TABLE par_table;
表已删除。
6. 索引重命名
SQL> ALTER INDEX create_date_ind2 RENAME TO create_date_ind;
索引已更改。
7. 验证
sql> select partitioned from user_tables where table_name = 'UNPAR_TABLE';
par
---
yes
sql> select partition_name from user_tab_partitions where table_name = 'UNPAR_TABLE';
partition_name
------------------------------
p1
p2
p3
p4
sql> select count(*) from unpar_table;
----------
sql> select count(*) from unpar_table partition (p4);
----------
sql>
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21381303/viewspace-1115548/ ,如需转载,请注明出处,否则将追究法律责任。