需要将数据库中的几个表从USER A 移动到USER B下面,在ORACLE中,这个叫做更改表的所有者或者修改表的Schema。
CREATE TABLE TEST.KKK
( ID INT,
NAME VARCHAR2(12) ,
CONSTRAINT PK_KKK PRIMARY KEY(ID)
);
INSERT INTO TEST.KKK VALUES(1000, 'kerry');
commit;
方法1: 常规方法,在目标用户下创建表,并拷贝数据过去。
CREATE TABLE TEST1.KKK( ID INT, NAME VARCHAR2(12) ,CONSTRAINT PK_KKK PRIMARY KEY (ID));
INSERT INTO TEST1.KKK SELECT * FROM TEST.KKK;
COMMIT;
DROP TABLE TEST.KKK;
当然也可以使用CREATE TABLE TEST1.KKK AS SELECT * FROM TEST.KKK;
但是使用这种方式需要注意,索引和约束都无法Copy过去。所以一定要慎用 CREATE TABLE AS (CTAS)这种语法。
方法2: 使用expdp/impdp,导出表然后导入表修改表的Schema。使用exp/imp方式也是差不多,在此不做介绍。
expdp system/xxxx tables=test.kkk directory=data_pump_dir dumpfile=kkk.dmp logfile=kkk.log
impdp system/xxxx tables=test.kkk directory=data_pump_dir remap_schema=test:test1 dumpfile=kkk.dmp logfile=import.log
注意上面方法无法移动表到其它表空间,所以,如果你也必须移动表到对应的表空间,
那么就必须使用参数 remap_tablespace, 如下所示:
impdp system/xxxxx tables=test.kkk directory=data_pump_dir remap_schema=test:test1 remap_tablespace=tbs_test_data:tbs_test1_data dumpfile=kkk.dmp logfile=import.log
实际场景当中,那些需要修改Schema的表可能会非常大,
生产环境完全不能使用方法3这种捷径。如果使用CTAS这种方法,即使使用NOLOGGING和开启并行,也是非常消耗资源和时间的。
使用expdp/impdp 稍微好一些,但是也不能避免一些资源开销。
还有一种方法就是使用exchange partition,exchange只是在ORACLE的数据字典中修改了分区和表的结构。
数据并未发生任何修改,因此速度很快.对于大表来说,非常高效!
create table test.big_table as select object_id, object_name from dba_objects;
create table test1.big_table
(
object_id number,
object_name varchar2(128)
)
partition by range( object_id)
(
partition big_table_par values less than(maxvalue)
);
alter table test1.big_table exchange partition big_table_par with table test.big_table;
select count(*) from test1.big_table;
COUNT(*)
----------
72329
select count(*) from test.big_table;
COUNT(*)
----------
0
如上所示,我们假设test.big_table是一个非常大的表,那么使用exchange partition就能快速、高效地将一个大表修改Schema,
唯一不足的是,需要将普通表修改为分区表,当然,很多时候,大表很可能已经是分区表,使用这种方式不会有任何修改。
另外,我们上面都是测试普通表,其实如果是分区表,使用exchange partition则是最佳选择!
参考资料:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:752030266230




