[Oracle19C 数据库管理] 加载和传输数据库

移动数据的通用架构

数据泵data pump(impdp, expdp),借助DBMS_DATAPUMP存储过程,可以进行表的导出导入,行记录的导出导入,表空间的导出导入或者整个schema的导出导入。使用数据泵可以在两个不同版本的数据库或者两个异构的数据库之间进行数据的传递。

SQL*Loader(sqlldr),可以从外部读取文本,通过OracleLoader编译器,将本文加载到表里面。也支持外部表,将外部数据直接加载到Oracle数据库的内存当中。

数据泵(用于Oracle数据库之间传递数据)

在数据库之间移动数据非常好用的工具,使用expdp对数据进行导出, 使用impdp对数据进行导入。
expdp将表里每一行数据读取出来,使用固定的分隔符,写入到操作系统的文件中,例如导出一个一万行数据的表,就需要写一万行数据。数据泵可以并行, 可以将这1万条数据同时写到10个文件中,可以提高数据导出的速度。impdp在导入的时候,也可以开启10个并行读,来提高导入的效率。
expdp在导出的时候,有个Master表会记录他的进度,如果中断了,可以继续进行导出。
导出并不是备份的一种方式,但是做备份的时候,可以把重要的表进行导出。

数据泵的好处

  • 可以对敏感的对象或行记录进行导出。
  • 可以排除数据库的一些对象。
  • 可以并行操作。
  • 可以跨网络进行导出。
  • 导入的时候可以重新分配对象的名字(remapping)。
  • 可以只导表结构而不导数据。
  • 导出时可以选择压缩和加密
  • 可以导出CLOB字段。

实作: 使用itleo导出hr.employees表

pdbadmin登录,创建directory对象,并给itleo授予读写权限。
SQL> conn pdbadmin/oracle@pdb1
Connected.

SQL> create or replace directory mydir as '/home/oracle';
Directory created.

退出sqlplus到命令行
[oracle@ol7-19c ~]$ expdp itleo/oracle@pdb1 directory=mydir dumpfile=mydum.dmp tables='test001'

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.
Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Starting "ITLEO"."SYS_EXPORT_TABLE_01":  itleo/********@pdb1 directory=mydir dumpfile=mydum.dmp tables=test001
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "ITLEO"."TEST001"                           112.0 MB 16777216 rows
Master table "ITLEO"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for ITLEO.SYS_EXPORT_TABLE_01 is:
  /home/oracle/mydum.dmp
Job "ITLEO"."SYS_EXPORT_TABLE_01" successfully completed at Sun Feb 5 12:35:05 2023 elapsed 0 00:00:13

******************************************************************************
Dump file set for ITLEO.SYS_EXPORT_TABLE_01 is:
  /home/oracle/mydump.dump
Job "ITLEO"."SYS_EXPORT_TABLE_01" successfully completed at Sun Feb 5 12:18:29 2023 elapsed 0 00:00:17

实作: 导入刚才导出的dmp文件,因为数据表重名,remap另外一个名字。

[oracle@ol7-19c ~]$ impdp itleo/oracle@pdb1 directory=mydir dumpfile=mydum.dmp remap_table=test001:test002

Import: Release 19.0.0.0.0 - Production on Sun Feb 5 12:36:31 2023
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Master table "ITLEO"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "ITLEO"."SYS_IMPORT_FULL_01":  itleo/********@pdb1 directory=mydir dumpfile=mydum.dmp remap_table=test001:test002
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "ITLEO"."TEST002"                           112.0 MB 16777216 rows
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Job "ITLEO"."SYS_IMPORT_FULL_01" successfully completed at Sun Feb 5 12:36:44 2023 elapsed 0 00:00:12


登录数据库进行验证
[oracle@ol7-19c ~]$ sqlplus itleo/oracle@pdb1
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> select table_name from user_tables;

TABLE_NAME
---------------
TEST001
TEST002

SQL*Loader(用于非Oracle数据库传递数据)

Input data files, 从其他数据库导出的文本文件
control file, 告诉SQLLoader是用什么样的格式来读取文本文件,分隔符是什么,字段类型。
通过控制文件,将数据文件的内容读到SQLLoader的编译器中,符合条件的插入到数据库。不符合条件的放到bad file中。如果bad file超过一定的行数,剩余的文本都不在处理,都放到discard文件中。

控制文件可以编写的内容

LOAD DATA      #告诉SLQLoader要加载数据
INFILE '数据文件完整路径'   #告诉SLQLoader 数据文件路径
BADFILE 'bad file的完整路径'    #告诉SLQLoader bad文件路径
DISCARDFILE 'discard文件的完整路径'   #告诉SLQLoader discard文件路径
APPEND            #默认加载时清除表中的数据,使用这个子句可以让SQLLoader不清除现有数据
INTO TABLE 数据表名      #告诉SLQLoader插入到哪个表
TRAILING NULLCOLS       #数据文件中缺少某个字段的内容,则当作空值。
(
   字段定义, 
   字段定义,
   ...
   字段定义
)

SQLLoader加载有两种方式,传统加载和直接路径加载(Direct Path load)。

传统加载可以加载蔟表(Cluster),直接路径加载不可以。
传统加载允许加载过程中其他用户修改表,直接路径加载会阻塞对表的修改。
传统加载会插入每一行时进行索引的维护,直接路径加载会在加载结束后merge索引。
传统加载会触发所有的约束,直接路径加载只会触发主键约束、唯一约束和非空约束。

导入的命令最后加上direct=y 则为直接路径加载。

[oracle@ol7-19c ~]$ sqlldr itleo/edppde_7500@pdb1 control='/home/oracle/sqlldr.ctl' direct=y
Path used:      Direct
Load completed - logical record count 6.

Table TEST_LOADER:
  5 Rows successfully loaded.

Check the log file:
  sqlldr.log
for more information about the load.

实作: SQL*Loader导入数据

itleo登录到pdb1中,创建一个测试数据库test_loader
SQL> create table test_loader (a1 number, a2 varchar2(30), a3 date, a4 number);
Table created.

在命令行工具中,在/home/oracle中创建一个控制文件sqlldr.txt

[oracle@ol7-19c ~]$ cat sqlldr.txt
load data
infile '/home/oracle/data.txt'   #数据文件路径
into table test_loader           #控制文件路径
replace                          #如果重复则替换
fields terminated by ','         #字段之间使用,分割
trailing nullcols                #如果空值则插入null
(a1, a2, a3 "to_date(:a3, 'yyyy-mm-dd hh24:mi:ss')",a4)      #四个值分别插入表的a1-a4字段,a3字段进行数据转换



在/home/oracle中创建一个控制文件data.txt
[oracle@ol7-19c ~]$ cat data.txt
20,Ryan Smith,1980-01-28 00:00:00,800
30,Allen Wheels,1981-01-20 00:00:00,1600
30,Leo Zhang,1981-04-24 10:00:00,2400
a1,,,,,                                            #数据类型不对,字段不匹配
30,Allen Wheels,1981-01-20 00:00:00,1600,111       #多一个字段
20,Ryan Smith,1980-01-28 00:00:00                  #少一个字段

导入SQL*Loader
[oracle@ol7-19c ~]$ sqlldr itleo/edppde_7500@pdb1 control='/home/oracle/sqlldr.txt' bad='/home/oracle/sqlbad.txt' log='/home/oracle/sqllog.txt'

SQL*Loader: Release 19.0.0.0.0 - Production on Sun Feb 5 13:03:00 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 6

Table TEST_LOADER:
  5 Rows successfully loaded.

Check the log file:
  /home/oracle/sqllog.txt
for more information about the load.

多一列和少一列的数据都导入了,只有“数据类型不对,字段不匹配”的那一行没有导入。

SQL*Loader Express

SQLLoader Express不需要控制文件,指定数据表名.dat向数据表插入数据。
表的列只能是标量类型(character, number, datetime)。
SQLLoader Express使用表的列名来定义导入的数据类型。

实作: 将test005.dat中的数据插入到itleo.test005数据库。

[oracle@ol7-19c ~]$ cat test005.dat
20,Ryan Smith,800
[oracle@ol7-19c ~]$ sqlldr itleo/edppde_7500@pdb1 table='test005'

SQL*Loader: Release 19.0.0.0.0 - Production on Sun Feb 5 14:58:07 2023
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Express Mode Load, Table: TEST005
Path used:      External Table, DEGREE_OF_PARALLELISM=AUTO

Table TEST005:
  1 Row successfully loaded.

Check the log files:
  test005.log
  test005_%p.log_xt
for more information about the load.

外部表


外部表通过SQLLoader将外部的txt转换到内存中的表,这个表可以再次处理插入到物理表中持久化。
外部表也可以借助数据泵的导出和导入二进制数据文件,把数据通过Oracle引擎处理完,再把结果集写入到二进制数据文件中。

实作: 创建一个外部表

  • 创建/home/oracle/sqlldr目录,用来存放外部表文件。

  • 在sqlplus中创建一个只想外部表目录的directory

SQL> create or replace directory ext_tab as '/home/oracle/sqlldr';
Directory created.

因为使用的itleo创建的,所以不需要给自己创建的directory读写权限。
以下语句不需要运行: 
       grant read,write to directory ext_tab to itleo;
  • 在/home/oracle/sqlldr中创建foo.dat,并写入外部表的数据。
[oracle@ol7-19c sqlldr]$ cat foo.dat
10,Leo,Zhang,1000
20,Winston,Wang,1000
  • 数据库中创建外部表
create table ext_emp_table (id number, first_name varchar2(20), last_name varchar2(20), salary number)
organization external
(
  type oracle_loader
  default directory ext_tab
  access parameters (fields terminated by ',')
  location ('foo.dat')
) reject limit 200;


SQL> select * from ext_emp_table;

        ID FIRST_NAME           LAST_NAME                SALARY
---------- -------------------- -------------------- ----------
        10 Leo                  Zhang                      1000
        20 Winston              Wang                       1000

使用数据泵将结果集导出放到外部文件中,每次访问外部表,都回到外部文件访问数据。
如果外部文件不存在了,就无法查询数据了。

实作: 使用oracle_datapump创建外部表

create table ext_emp_query_result (employee_id, salary)
organization external
(
  type oracle_datapump
  default directory ext_tab
  location ('empl.exp')
)
parallel
as
select employee_id, salary from hr.employees;



SQL> select * from ext_emp_query_result where rownum<=5;
EMPLOYEE_ID     SALARY
----------- ----------
        198       2600
        199       2600
        200       4400
        201      13000
        202       6000

posted on 2023-02-05 15:47  LeoZhangJing  阅读(254)  评论(0编辑  收藏  举报

导航