SPL:数据转储
应用中有时会把某个数据库中的部分数据转储到另一个数据库,如果同类数据库且数据结构相同,则可以使用数据库DUMP工具来做。如果是异构数据库则一般会使用文本文件作为中介,但文本文件可能丢失数据类型信息,而且速度也比较慢。
SPL提供了二进制数据格式,可以较高性能实现数据转储功能。还能支持数据结构不完全一致的情况。
1. 导出
1.1 小数据量
ORACLE数据库中有一张ORDERS表,现在要把表中数据导出为SPL集文件,编写SPL脚本如下:
A |
B |
|
1 |
=connect("oracle") |
//连接数据库 |
2 |
=A1.query@x("SELECT ORDERKEY, ORDERDATE, CUSTKEY, PRICE, AMOUNT FROM ORDERS WHERE ORDERDATE>=DATE ’2020-01-01’") |
//查出表中需要导出的数据,关闭数据库连接 |
3 |
=file("orders.btx").export@b(A2) |
//将A2中查出数据导出到文件 |
导出时可能是整表数据,也可能是部分列或符合某种条件的数据,由A2格中的SQL语句决定。
集文件是SPL专用的二进制数据文件,自动记录了数据值的数据类型,在读入时不用再解析判断数据类型,比TXT文件读入速度要快得多。数据表导出成TXT文件时会丢失一些信息,比如身份证号之类的长数字文本串,在导入时可能会被解析成数值。
这里导出数据是使用数据库的JDBC驱动,当数据量比较大时,就会暴露出JDBC性能不佳的问题,导出比较费时。此时可以利用SPL的并行功能提高取数效率,详情请参阅《SPL:并行取数技术》。
1.2 大数据量
当要导出的数据量很大,不能全部装入内存中时,要使用游标来读数。
A |
B |
|
1 |
=connect("oracle") |
//连接数据库 |
2 |
=A1.cursor@x("SELECT ORDERKEY, ORDERDATE, CUSTKEY, PRICE, AMOUNT FROM ORDERS WHERE ORDERDATE>=DATE ’2020-01-01’") |
//创建取数游标,选项@x表示游标关闭时也关闭数据库连接 |
3 |
=file("orders.btx").export@b(A2) |
//将A2游标中数据导出到文件 |
2. 导入
将集文件数据导入到另一数据库中。
2.1 目标数据结构相同
当文件中字段结构与数据表中完全相同时,例如将orders.btx导入到库中的ORDERS表,SPL脚本如下:
A |
B |
|
1 |
=file("orders.btx").cursor@b() |
//创建读取文件数据的游标 |
2 |
=connect("oracle") |
//连接数据库 |
3 |
=A2.update@i(A1,ORDERS) |
//将A1的数据插入到表中,文件字段名与表中相同 |
4 |
>A2.close() |
//关闭数据库连接 |
A3中的选项@i表示数据全部都是新增加的,用INSERT插入方式导入,可提高导入速度。如果要导入的数据与数据表中数据有主键重复的,是对原有数据的更新修改,就直接用无选项的update函数,会与表中数据比对,决定是用INSERT还是UPDATE方式导入数据。
有时导入数据时,可能需要清除数据表中原有数据后,将文件中数据全表复制,例如将customer.btx文件全表复制到CUSTOMER表中,SPL脚本如下:
A |
B |
|
1 |
=file("customer.btx").cursor@b() |
//创建读取文件数据的游标 |
2 |
=connect("oracle") |
//连接数据库 |
3 |
=A2.update@a(A1,CUSTOMER) |
//选项@a表示执行前先清空CUSTOMER表中数据 |
4 |
>A2.close() |
//关闭数据库连接 |
2.2 目标数据结构不同
数据表对应文件中的某些字段改了名字,或者还有新增加的字段,SPL脚本如下:
A |
B |
|
1 |
=file("orders.btx").cursor@b() |
//创建读取文件数据的游标 |
2 |
=connect("oracle") |
//连接数据库 |
3 |
=A2.update@i(A1,ORDERS,ORDERKEY,ORDERDATE,CUSTID:CUSTKEY,PRICE,AMOUNT,REMARK:null) |
//将A1的数据导入到ORDERS表中 |
4 |
>A2.close() |
//关闭数据库连接 |
ORDERKEY、ORDERDATE、PRICE、AMOUNT字段名没变,文件中的CUSTKEY字段改名为CUSTID了,REMARK是新增的字段,赋值为null。
更多信息可以查阅SPL文档中db.update函数帮助。
我有一个 70 万行 30 列的 excel 文件,后缀是 xlsx 格式,可不可以实现在十秒内转存为 btx 格式?
目前的做法是,先用’xlsimport@c 读成游标,然后再用游标的方式写出去,file(“文件.btx”).export@b(游标),但效率不理想。
恳请大佬指点一下!
试一下 for cs,1000 读一遍数据的时间,这是 poi 和 excel 决定的,我们没办法
谢谢老贼指点🙏
您的方法可以,比我自己捣腾的方法少了一半的时间。
73 万行,31 列的 xlsx 转存为 btx,本机 (mac 里的 win 虚拟机,6G 内存) 平均耗时在 25 秒左右。