数据库之间转储数据的方法

在数据库之间进行数据转储,需要先将源数据库的数据导出到某文件,再把该文件中的数据导入到目标数据库中。还会有些较复杂的场景,需要对导出的文件进行一些处理后再导入到目标库。本文将探讨几种数据库转储使用的文件类型并加以对比。

数据库工具

数据库本身自带了一些数据导出导入工具,直接用这些工具可以快速完成线下数据的简单转储。例如,数据的备份与恢复、同类数据库同结构表的数据转储或是其他一些较为简单的数据迁移。

以MySQL为例,要实现同类数据库同结构表的数据转储,可先将表中数据导出成文本文件,SQL如下:

select
            *
into
            outfile "/home/raqsoft/lineitem.txt"
from
            LINEITEM;

再将文本文件中的数据导入同结构的数据表,SQL如下:

load data infile "/home/raqsoft/lineitem.txt"
into
            table LINEITEM1;

使用MySQL还可以通过mysqldump和mysqlimport命令进行数据的导出导入。类似地,Oracle可以用spool和sqlldr。

编程实现转储数据

但是,有些情况难以直接使用数据自带的工具。例如,导出的文件结构与目标表数据结构不同、数据需要修改后再导入、带有动态查询条件的转储等,这类转储经常还可能要在应用程序里提供成功能被调用。这时就需要通过编程将源数据库中的数据导出到中介文件,再把文件的数据或处理后导入到目标数据库。

文本文件

文本文件是较常见的转储中介,它的通用性较强且没有内容大小的限制,但导出到文本文件后的数据会丢失数据类型。从文本文件读取数据时都变成了字符串,需要按指定的数据类型进行转换后使用。在实际开发过程中,要写个通用的读取文本文件工具类难度也较大。

Excel

还可以用Excel作为转储数据的中介文件,相比文本文件,Excel的单元格信息中带有数据类型。但是,Excel文件有行列数限制(xls文件:最大65536行,最多256列;xlsx文件:最大1048576行,最多16384列),需要导出的数据量超过限制时,处理起来就很麻烦了。Excel相比文本文件也更复杂,相同的数据,导出导入速度比文本文件要慢。

集算器的集文件

如果用集算器 SPL的集文件(btx),则没有上述文件的问题,btx是专用的二进制格式文件,自动记录了数据的数据类型,不会出现文本文件丢失数据类型的情况,且读取集文件时不用再解析判断数据类型,速度比文本文件要快。而且,集文件没有内容大小的限制,相比Excel,导出时无需因为内容大小限制被迫将数据分段存储。此外,还可根据需求在已有的集文件中继续追加数据。当文件较大时,读取数据可以利用分段并行,提升效率。

但是无论使用哪种类型的文件做为中介文件,最终还是需要编码来实现数据的处理。

使用SPL完成转储数据

SPL是专门为结构化(半结构化)数据设计的编程语言,有完整的文本文件和Excel文件处理能力,从文件读取数据的代码如下:

txt文件:=file("Department.txt").import@t(DEPT,MANAGER:int,...)

csv文件:=file("Department.csv").import@tc(DEPT,MANAGER:int,...)

Excel文件:=file("Department.xlsx").xlsimport@t(DEPT,MANAGER,...; "sheet1")

将数据导出到文件的代码如下:

txt文件:=file("Department.txt").export@t(data)

csv文件:=file("Department.csv").export@tc(data)

Excel文件:=file("Department.xlsx").xlsexport@t(data; "sheet1")

数据量较大时,还可以对文件创建游标后,基于游标进行运算,或将游标中的数据读出后写到文件。

使用SPL编码,无论选择哪种中介文件,都可以方便地完成数据库间转储数据。

例如,处理目标表数据结构不同情况,SPL可以这样写:=db.update(file,tablename,field1,filed2,CUSTID:CUSTKEY,field4,field5,REMARK:null),文件中的CUSTKEY字段改名为CUSTID了,REMARK是新增的字段,赋值为null。

又例如,处理数据改变后再导入的情况,文件中有名为data_date的列,数据类型为字符串,需要按yyyyMMdd的格式将串变为日期后导入新的数据表中,那么SPL可以这样写=db.update(file,tablename,field1,field2...,data_date:date(data_date,"yyyyMMdd"),...,fieldn)

线下数据转储也可能出现较复杂情况,比如根据动态条件过滤文件中的数据,再将结果导入到目标数据库,这需要编写出可以解析动态表达式的程序,难度较大,调试也较为复杂。可以用SPL配合数据库自带的工具,完成转储,例如:

A B
1 =file("info.txt").cursor@t(id:int,...,type:int,sdate:date) //info为数据库工具导出的文本文件,创建读取文本文件数据的游标,并指定字段类型
2 =A1.select(type==3 && sdate>=date("2021-01-01")) //根据条件过滤数据,这里的条件可以看作动态传入的参数

若过滤后的结果较小,可以直接通过jdbc将数据导入数据库,例如:

A B
3 =connect("mysql") //连接数据库
4 =A3.update@i(A2,INFO) //将A2的数据插入到表中,字段名与表相同
5 >A3.close() //关闭数据库连接

或将处理后的结果再导出成文本文件,最后由数据库工具导入到目标表。

SPL很容易被JAVA 集成而使转储数据的功能在应用程序中使用,进一步信息可参考:《Java 如何调用 SPL 脚本》。