浅谈exp/imp(上) (r5笔记第81天)
作为DBA,经常需要在不同数据库环境间做数据的导入导出,exp/imp就是这样的轻便快捷的客户端工具,可以很方便的在不同数据库之间转移数据对象,即使数据库位于不同的硬件或者软件平台上。exp会转储产生对应的二进制文件,里面包含数据的定义信息,数据内容等,也就是我们通常所说的dump文件。
exp/imp是比较经典的数据导出导入工具,不过自expdp/impdp推出以来,exp/imp还是受到了不少的冷落,在新的数据库版本中,支持力度都集中在了expdp/impdp上面。Expdp/impdp是基于服务端的数据导入导出工具,性能上和功能上要更胜一筹,不过不管怎样,exp/imp确实是一款比较轻巧的工具,对于小表的处理效果还是相当不错的。
使用exp/imp的场景
使用exp/imp主要有4种模式:数据库模式,表模式,用户模式,可传输表空间模式,在此基础上使用比较多的还有基于query选项的数据选择性抽取和数据结构导出。
数据库模式
数据库模式主要是作为全库备份使用的,可以导出除sys之外的数据库里的所有对象,在数据量较小的情况下是一个不错的选择。
exp n1/n1 file=db_backup.dmp full=y
表模式
表模式可以导出某个用户下指定的表,比如我们需要导出的表名为:test1,test2
exp n1/n1 file=table_mode.dmp tables=test1,test2
用户模式
用户模式可以导出指定用户下所有的对象,比如导出用户user1下所有的对象
exp n1/n1 file=user_mode.dmp owner=user1
传输表空间模式常作为数据迁移时的一种方法,在数据迁移篇中会有详细的描述 海量数据迁移之传输表空间(一) http://blog.itpub.net/23718752/viewspace-1703358/
同理,imp中也会存在同样的四种模式,使用方法都是类似的。
除了常用的4种模式之外,使用query选项选择性导出数据也是一种很使用的方法。比如存在一个表test,我们希望根据字段object_type=’TABLE’的条件来选择性导出数据,可以使用query选项完成。
使用Query选项做选择性数据导出
exp n1/n1 file=query_bak.dmp query=" where object_type= 'TABLE' " tables=test
得到对象的ddl语句
还有一个功能点可能大家不太注意,就是能够很方便得到ddl相关的语句。
比如我们希望得到表test的建表语句,可以通过exp/imp这么做。
exp n1/n1 rows=n compress=n tables=test file=test.dmp log=exp_test.log buffer=10240000
imp n1/n1 rows=n full=y ignore=y show=y file=test.dmp log=imp_test.log buffer=10240000
得到的建表语句就会是下面的样子。
import done in AL32UTF8 character set and AL16UTF16 NCHAR character set
. importing N1's objects into N1
. importing N1's objects into N1
"CREATE TABLE "TEST" ("OWNER" VARCHAR2(30) NOT NULL ENABLE, "OBJECT_NAME" VA"
"RCHAR2(30) NOT NULL ENABLE, "SUBOBJECT_NAME" VARCHAR2(30), "OBJECT_ID" NUMB"
"ER NOT NULL ENABLE, "DATA_OBJECT_ID" NUMBER, "OBJECT_TYPE" VARCHAR2(19), "C"
"REATED" DATE NOT NULL ENABLE, "LAST_DDL_TIME" DATE NOT NULL ENABLE, "TIMEST"
"AMP" VARCHAR2(19), "STATUS" VARCHAR2(7), "TEMPORARY" VARCHAR2(1), "GENERATE"
"D" VARCHAR2(1), "SECONDARY" VARCHAR2(1), "NAMESPACE" NUMBER NOT NULL ENABLE"
", "EDITION_NAME" VARCHAR2(30)) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 2"
"55 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GRO"
"UPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS"
"CREATE INDEX "IDX_TEST" ON "TEST" ("OBJECT_ID" DESC , "OBJECT_NAME" , "OBJE"
"CT_TYPE" ) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1"
"048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABL"
"ESPACE "USERS" LOGGING"
看起来确实是不太直观,如果自己想直接使用还得手工格式化,这个时候我们可以借助awk来格式化一下。看起来好像挺抽象,但是功能还是很强大的。
awk '
/ "BEGIN / { N=1; }
/ "CREATE / { N=1; }
/ "CREATE INDEX/ { N=1; }
/ "CREATE UNIQUE INDEX/ { N=1; }
/ "ALTER / { N=1; }
/ " ALTER / { N=1; }
/ "ANALYZE / { N=1; }
/ "GRANT / { N=1; }
/ "COMMENT / { N=1; }
/ "AUDIT / { N=1; }
N==1 { printf "n/n"; N++ }
/"$/ {
if (N==0) next;
s=index( $0, """ );
ln0=length( $0 )
if ( s!=0 ) {
lcnt++
if ( lcnt >= 30 ) {
ln=substr( $0,s+1,length( substr($0,s+1))-1)
t=index( ln, ")," )
if ( t==0 ) { t=index( ln, ", " ) }
if ( t==0 ) { t=index( ln, ") " ) }
if ( t > 0 ) {
printf "%sn%s",substr( ln,1,t+1), substr(ln, t+2)
lcnt=0
}
else {
printf "%s", ln
if ( ln0 < 78 ) { printf "n" ; lcnt=0 }
}
}
else {
printf "%s",substr( $0,s+1,length( substr($0,s+1))-1 )
if ( ln0 < 78 ) { printf "n" ; lcnt=0 }
}
}
}
END { printf "n/n"}
' imp_test.log |sed '1,2d; /^$/ d;
s/STORAGE *(INI/~ STORAGE (INI/g;
s/, "/,~ "/g;
s/ ("/~ &/g;
s/PCT[FI]/~ &/g;
s/[( ]PARTITION /~&/g;
s/) TABLESPACE/)~ TABLESPACE/g;
s/ , / ,~/g;
s/ DATAFILE /&~/' | tr "~" "n"
看看格式化后的结果,如此显著的结果是不是有一种马上想试试的冲动。
CREATE TABLE "TEST"
("OWNER" VARCHAR2(30) NOT NULL ENABLE,
"OBJECT_NAME" VARCHAR2(30) NOT NULL ENABLE,
"SUBOBJECT_NAME" VARCHAR2(30),
"OBJECT_ID" NUMBER NOT NULL ENABLE,
"DATA_OBJECT_ID" NUMBER,
"OBJECT_TYPE" VARCHAR2(19),
"CREATED" DATE NOT NULL ENABLE,
"LAST_DDL_TIME" DATE NOT NULL ENABLE,
"TIMESTAMP" VARCHAR2(19),
"STATUS" VARCHAR2(7),
"TEMPORARY" VARCHAR2(1),
"GENERATED" VARCHAR2(1),
"SECONDARY" VARCHAR2(1),
"NAMESPACE" NUMBER NOT NULL ENABLE,
"EDITION_NAME" VARCHAR2(30))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE (INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" LOGGING NOCOMPRESS
/
CREATE INDEX "IDX_TEST" ON "TEST"
("OBJECT_ID" DESC ,
"OBJECT_NAME" ,
"OBJECT_TYPE" )
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE (INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" LOGGING
/
- Golang Stub初体验
- 厚土Go学习笔记 | 20. slice 继续
- 数据挖掘算法之深入朴素贝叶斯分类
- 歪?我想要一个XXE。
- 厚土Go学习笔记 | 19. slice和数组很像,但是slice可以添加元素
- 工具| 手把手教你制作信息收集器之网站备案号
- 厚土Go学习笔记 | 18. 数组
- 厚土Go学习笔记 | 17. 结构体及用指针访问结构体
- Java枚举类型的原理
- 厚土Go学习笔记 | 27. 斐波纳契闭包
- 代码审计| APPCMS SQL-XSS-CSRF-SHELL
- 厚土Go学习笔记 | 33. 利用数据流实现密码代换功能
- 厚土Go学习笔记 | 32. Readers读取数据流
- GoStub框架二次开发实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于二叉树,你该了解这些!
- 双指针法:总结篇!
- 栈与队列:总结篇!
- Appium移动端自动化测试--元素操作与触摸动作【移动端自动化测试教程奉上】
- 接口测试Mock利器--moco runner是如何工作的?
- Java中类型判断的几种方式
- 如何实现类似@Component的Spring动态注入功能
- 一次代码优化实践,用了模板方法+策略+工厂方法模式
- 给 JDK 报了一个 P4 的 Bug,结果居然……
- Git | Git Server 搭建
- leetcode树之二叉树的深度
- Nic*app的native层算法破解
- ActiveMq的顺序性消费问题
- 佳能遭严重勒索软件攻击,10TB数据被窃取,大量服务宕机
- 进程线程剖析(二)-进程组成、状态与特点