dmfldr
1.简介
dmfldr(DM Fast Loader)是 DM 提供的快速数据装载命令行工具。用户通过使用dmfldr 工具能够把按照一定格式排序的文本数据以简单、快速、高效的方式载入到 DM 数据库中,或把 DM 数据库中的数据按照一定格式写入文本文件。
2.dmfldr使用
2.1dmfldr使用格式
安装好 DM 数据库管理系统后,在安装目录的”bin”子目录下可找到 dmfldr 执行文
件。启动操作系统的命令行窗口,进入”dmfldr”所在目录。
dmfldr 的使用必须指定必要的参数,否则工具会报错“无效的参数个数”并退出。为
dmfldr 指定参数的格式为:
dmfldr keyword=value [keyword=value ...] |
例如:
dmfldr USERID=SYSDBA/SYSDBA CONTROL='c:\fldr.ctl' |
USERID 和 CONTROL 是启动 dmfldr 必须要指定的参数,且 USERID 必须是第一个参数,CONTROL 必须是第二个参数。
2.2dmfldr参数
dmfldr 使用较为灵活,参数较多,字符串类型参数必须以引号封闭。具体参数如下:
关键字 | 说明(默认值) |
USERID | 用户名/口令格式:USER/PWD@SERVER:PORT#SSL_PATH@SSL_PWD |
CONTROL | 控制文件,字符串类型 |
LOG | 日志文件,字符串类型 (fldr.log) |
BADFILE | 错误数据记录文件,字符串类型 (fldr.bad) |
SKIP | 初始忽略逻辑行数 (0) |
LOAD | 需要装载的行数 (ALL) |
ROWS | 提交频次 (50000), DIRECT 为 FALSE 有效 |
DIRECT | 是否使用快速方式装载 (TRUE) |
SET_IDENTITY | 是否插入自增列 (FALSE) |
SORTED | 数据是否已按照聚集索引排序 (FALSE) |
INDEX_OPTION | 索引选项 (1) 1不刷新二级索引,数据按照索引先排序,装载完后再将排序的数据插入索引 2不刷新二级索引,数据装载完成后重建所有二级索引 3 刷新二级索引, 数据装载的同时将数据插入二级索引 |
ERRORS | 允许的最大数据错误数 (100) |
CHARACTER_CODE | 字符编码,字符串类型 (GBK, GB18030,UTF-8, SINGLE_BYTE, EUC-KR) |
MODE | 装载方式,字符串类型 IN 表示载入,OUT 表示载出,OUTORA 表示载出 ORACLE (IN) |
CLIENT_LOB | 大字段目录是否在本地 (FALSE) |
LOB_DIRECTORY | 大字段数据文件存放目录 |
LOB_FILE_NAME | 大字段数据文件名称,仅导出有效 (dmfldr.lob) |
BUFFER_NODE_SIZE | 读入文件缓冲区的大小 (10),有效值范围 1~2048 |
READ_ROWS | 工作线程一次最大处理的行数 (100000),最大支持 2^26-10000 |
NULL_MODE | 载入时 NULL 字符串是否处理为 NULL 载出时空值是否处理为 NULL 字符串 (FALSE) |
NULL_STR | 载入时视为 NULL 值处理的字符串 |
SEND_NODE_NUMBER | 运行时发送节点的个数 (20),有效值范围 16~65535 |
TASK_THREAD_NUMBER | 处理用户数据的线程数目,默认与处理器核数量相同,有效值范围 1~128 |
BLDR_NUM | 服务器 BLDR 数目 (64),有效值范围 1~1024 |
BDTA_SIZE | bdta 的大小 (5000),有效值范围 100~10000 |
COMPRESS_FLAG | 是否压缩 bdta (FALSE) |
MPP_CLIENT | MPP 环境,是否本地分发 (TRUE) |
SINGLE_FILE | MPP环境,是否只生成单个数据文件(FALSE) |
LAN_MODE | MPP 环境,是否以内网模式装载数据(FALSE) |
UNREP_CHAR_MODE | 非法字符处理选项(0),为 0 时表示跳过该数据行,为 1 时表示使用(*)替换错误字节 |
SILENT | 是否静默方式装载数据(FALSE) |
BLOB_TYPE | BLOB 类型字段数据值的实际类型,字符串类型 (HEX_CHAR),HEX 表示值为十六进制,HEX_CHAR 表示值为十六进制字符类型,仅在 direct=FALSE 有效 |
OCI_DIRECTORY | OCI 动态库所在的目录 |
DATA | 指定数据文件路径 |
ENABLE_CLASS_TYPE | 允许用户导入 CLASS 类型数据 (FALSE) |
FLUSH_FLAG | 提交时是否立即刷盘 (FALSE) |
IGNORE_BATCH_ERRORS | 是否忽略错误数据继续导入 (FALSE) |
SINGLE_HLDR_HP | 是否使用单个 HLDR 装载 HUGE 水平分区表 (FALSE) |
EP | 指定需要发送数据的站点序号列表,仅向 MPP 环境导入数据时有效 |
HELP | 打印帮助信息 |
2.3控制文件
控制文件 CONTROL 是启动 dmfldr 必须要指定的参数,用于指定数据文件中数据的格式。在数据载入时,dmfldr 根据控制文件指定的格式来解析数据文件;导出数据时,dmfldr 也会根据控制文件指定的列分隔符、行分隔符等生成数据文件。控制文件中还可以指定其他 dmfldr 参数值。
2.3.1控制文件语法
dmfldr 控制文件的语法如下所示:
[OPTIONS( <id>=<value> …… )] LOAD [DATA] INFILE < <file_option>|<directory_option> > [BADFILE <path_name>] [APPEND|REPLACE|INSERT] <into_table_clause> <id> ::=参数 <value> ::=值 <file_option> ::= [LIST] <path_name> [<row_term_option>] [,<path_name> [<row_term_option>]] <directory_option> ::= DIRECTORY <path_name> [<row_term_option>] <path_name> ::=文件地址 <row_term_option> ::=STR [X] <delimiter> <into_table_clause> ::= <into_table_single>{<into_table_single>} <into_table_single> ::=INTO TABLE [<schema>.]<tablename> [EP <ep_option>] [WHEN <field_conditions>] [FIELDS [TERMINATED BY] [X] <delimiter>] [<enclosed_option>] [<coldef_option>] <schema> ::=模式名 <tablename> ::=表名 <ep_option> ::=(<ep_list>) <ep_list> ::=整型数字列表,以逗号分隔 <field_conditions> ::= <field_condition>{ AND <field_condition>} <field_condition> ::= [(] <cmp_exp><cmp_ops><cmp_data>[)] <cmp_exp> ::= <colid> | (p1:p2) <cmp_ops> ::= = | <> | != <cmp_data> ::= [X] '<字符串常量>' | BLANKS | WHITESPACE <delimiter> ::='<字符串常量>' <coldef_option> ::=(<col_def>{ ,<col_def>}) <col_def>::=<col_id> [FILLER][<property_option>][<fmt_option>][<term_option>] [<enclosed_option>][<constant_option>][<fun_option>] <col_id> ::=列名 <property_option> ::=<position_option> | NULL <position_option> ::=position(p1:p2) | position(p1) <fmt_option> ::=DATE FORMAT '<时间日期格式串>' <term_option> ::= TERMINATED [BY] <wx_option> <wx_option> ::= WHITESPACE|[X] <delimiter> <enclosed_option> ::= [OPTIONALLY] ENCLOSE [BY] [X] <delimiter> <constant_option> ::= CONSTANT "<常量>" <fun_option> ::= "函数名称()" |
3.实战
3.1指定数据文件
3.1.1在控制文件中指定数据文件
我的windows环境下ezoffice用户下有张org_organization表,现将其导出,在d:\org\org.ctl,内容如下:
LOAD DATA INFILE 'd:\org\org.txt' INTO TABLE EZOFFICE.ORG_ORGANIZATION FIELDS '|' |
载出
D:\dmdbms\bin>dmfldr userid=ezoffice/123456789@127.0.0.1:5236 control='d:\org\org.ctl' mode='out' dmfldr V8 2412 rows is load out 总共导出 2412 行数据 用时:674.155(ms) |
导出的文本内容如下:
|
将上面windows环境导出的文件,导入到linux中的库中,先获取表结构,创建相同的表:
CREATE TABLE EZOFFICE.org_organization ( ORG_ID NUMBER(20,0) NOT NULL, ORGPARENTORGID NUMBER(20,0), ORGMANAGEREMPID VARCHAR2(160), ORGMANAGEREMPNAME VARCHAR2(100), ORGNAME VARCHAR2(600) NOT NULL, ORGSIMPLENAME VARCHAR2(200), ORGCODE VARCHAR2(64), ORGORDERCODE NUMBER(10,0), ORGFOUNDDATE TIMESTAMP(0), ORGDESCRIPTE VARCHAR2(600), ORGLEVEL NUMBER(2,0), ORGHASJUNIOR NUMBER(1,0), ORGSTATUS NUMBER(1,0), ORGIDSTRING VARCHAR2(1200), ORGNAMESTRING VARCHAR2(1200), ORGHASCHANNEL NUMBER(3,0), RTXDEPTID NUMBER(6,0), RTXDEPTPID NUMBER(6,0), ORGBANNER VARCHAR2(600), ORGSERIAL VARCHAR2(500), DOMAIN_ID NUMBER(20,0), ORGTYPE NUMBER(2,0) DEFAULT 0, GUID VARCHAR2(256), LASTUPDATE NUMBER(20,0), ORGCHANNELTYPE VARCHAR2(12) DEFAULT 0, ORGCHANNELURL VARCHAR2(400), ORG_ENGLISH_NAME VARCHAR2(1000), CHARGE_LEADER_IDS VARCHAR2(100), CHARGE_LEADER_NAMES VARCHAR2(150), WEBSERVICEURL VARCHAR2(500), ORGSTYLE VARCHAR2(100), ORGLAYOUT NUMBER(20,0), SCOPE_NAMES VARCHAR2(4000), SCOPE_USERIDS VARCHAR2(3000), SCOPE_ORGIDS VARCHAR2(2000), SCOPE_GROUPIDS VARCHAR2(2000), WIN_TITLE VARCHAR2(60), LOGO_FILENAME VARCHAR2(100), LOGO_SAVEFILENAME VARCHAR2(60), CONSTRAINT PK_ORG_ORGANIZATION NOT CLUSTER PRIMARY KEY(ORG_ID)); |
将导出的org.txt拷贝到/home/dmdba目录下,并在/home/dmdba下创建org.ctl控制文件,并且在控制文件里面指定数据文件,内容如下:
LOAD DATA INFILE '/home/dmdba/org.txt' INTO TABLE EZOFFICE.ORG_ORGANIZATION FIELDS '|' |
修改org.txt文件属主和属组
[root@localhost dmdba]# chown dmdba:dinstall org.txt |
导入:
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/org.ctl\' mode=\'in\' dmfldr V8 dmfldr: Copyright (c) 2011, 2015, Dameng. All rights reserved. Control file: Loaded rows: All Rows per commit to server: 50000 Rows to skip: 0 Errors count allowed: 100 Whether to load direct: Yes Whether to insert identity column: No Whether data is sorted by cluster index: No Character sets:GBK Data file counts: 1 /home/dmdba/org.txt Error file :fldr.bad Dest table :EZOFFICE.ORG_ORGANIZATION Column Name Packed data type End ORG_ID CHARACTER | ...... CHARACTER | LASTUPDATE CHARACTER | row buffer number is: 2 task thread number is: 1 2412 rows committed Dest table :EZOFFICE.ORG_ORGANIZATION 2412 Rows loaded success. Due to data format error, 0 rows abandon. Due to data error, 0 rows not loaded. Skip logic record counts: 0 Read logic record counts: 2412 Refuse logic record counts: 0 The total time used: 39.644(ms) |
这里需要注意的是,linux下单引号’是特殊符号,需要用\转移,否则报错如下:
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/org.ctl\' mode='in' dmfldr V8 parameters parse error[in] |
因为mode默认是in,所以载入的时候,mode可以省略
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/org.ctl\' |
另外控制文件里面注释要以--开头,不能以#作为注释。
3.1.2使用data参数指定数据文件
也可以使用 DATA 参数指定 dmfldr 的数据文件,数据文件路径的优先选择顺序为先
控制文件,后参数选项。如果控制文件中数据文件路径指定为‘*’,在命令行通过 DATA
参数指定数据文件路径,DATA 所指定的文件路径会替换‘*’。
将上面的控制文件修改为如下:
LOAD DATA INFILE * INTO TABLE EZOFFICE.ORG_ORGANIZATION FIELDS '|' |
导入:
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/org.ctl\' data=\'/home/dmdba/org.txt\' dmfldr V8 dmfldr: .... 2412 rows committed Dest table :EZOFFICE.ORG_ORGANIZATION 2412 Rows loaded success. Due to data format error, 0 rows abandon. Due to data error, 0 rows not loaded. Skip logic record counts: 0 Read logic record counts: 2412 Refuse logic record counts: 0 The total time used: 29.365(ms) |
需要注意的是,虽然data参数会替换控制文件里面INFILE的*,但控制文件里面INFILE不能不写,否则报错:
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/org.ctl\' data=\'/home/dmdba/org.txt\' dmfldr V8 Control file syntax error, line 2: INTO |
3.2数据转换与错误数据类型
dmfldr 使用的数据文件都是文本格式的,其中的列值都是以字符串的方式保存在数据文件中。要想将这些数据载入数据库表中,需要将字符串转换成数据库表各列对应的数据类型。dmfldr 支持所有 DM 数据库支持的列定义类型,包括字符串、数值、时间日期、时间日期间隔、大字段类型等。
若数据文件的编码方式与 DM 数据库服务器的编码方式不一样,dmfldr 还需要进行字符编码的转换。dmfldr 支持 UTF8、GBK 和 GB18030 编码之间的相互转换。数据类型和编码转换工作由 dmfldr 客户端进行,在这个过程中如果出现错误,dmfldr 会跳过该行继续后面的工作,并记录错误行到 BADFILE 指定的文件。常见的出错的情况有以下几种:
⚫ 编码转换失败
⚫ 目标列为字符串类型时,数据长度大于列定义长度
⚫ 目标列为数值类型时,数据包含非法字符或者转换后超出该数值的范围
⚫ 目标列为日期类型时,dmfldr 默认按 yyyy-mm-dd hh:mi:ss 的格式解析,如
果数据不是这样的格式,需要用format指定对应列的时间日期格式。
dmfldr 错误数据的文件路径由 BADFILE 参数设置,默认的错误文件名为 fldr.bad。用户也可以通过设置控制文件中的 OPTIONS 选项来指定错误数据文件的路径,同时也可以在控制文件的 LOAD 节点中指定错误数据文件的路径。错误数据文件路径最终值的优先选择顺序为 LOAD 节点选项,OPTIONS 选项,参数选项。用户可以同时对三种设置方式中的一个或多个设置,但最终的值只取一个。BADFILE 仅作用于 dmfldr 的工作 MODE 为 IN 的情况下,MODE 为 OUT 时无效。
允许的最大容错个数由 ERRORS 选项设置,默认为 100。当 dmfldr 客户端在数据类型和编码转换过程中出现的错误个数超过了ERRORS 所设置的数目,dmfldr 会停止载入,当前时间点的所有正确数据将会被提交到服务器端。如果载入过程中不允许出现错误则可以将 ERRORS 设置为 0;如果允许所有的错误出现,则可以将 ERRORS 设置为一个非常大的数。
例如:
- 脚本
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 INT,C3 DATE); |
- 编辑数据文件 test.txt,存放路径为/home/dmdba/test.txt,文件内容如下
1 1|2015-11-06 2 2|2015-11-05 3 3|2015-11_04 4 4|aaaa-bbb-ccc |
- 编辑控制文件 test.ctrl,存放路径为/home/dmdba/test.ctl,内容如下
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE test FIELDS '|' ( C1 TERMINATED BY ' ', C2, C3 DATE FORMAT 'yyyy-mm-dd' ) |
因为test.txt中第一列与第二列没有以竖线来分割,所以需要指定TERMINATED BY ' '来说明,表示空格符为结束符。同理如果test.txt中是逗号,如下
1, 1|2015-11-06 2, 2|2015-11-05 3, 3|2015-11_04 4, 4|aaaa-bbb-ccc |
则控制文件中写为C1 TERMINATED BY ','即可。
目标列为日期类型时,dmfldr 默认按 yyyy-mm-dd hh:mi:ss 的格式解析,所以对于C3列,要用FORMAT来格式化日期。
载入:
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' badfile=\'/home/dmdba/test.bad\' dmfldr V8 dmfldr: Copyright (c) 2011, 2015, Dameng. All rights reserved. Control file: ...... Character sets:GBK Data file counts: 1 /home/dmdba/test.txt Error file :/home/dmdba/test.bad Dest table :TEST Column Name Packed data type End C1 CHARACTER WHT C2 CHARACTER | C3 yyyy-mm-dd | row buffer number is: 2 task thread number is: 1 3 rows committed Dest table :TEST 3 Rows loaded success. Due to data format error, 0 rows abandon. Due to data error, 1 rows not loaded. Skip logic record counts: 0 Read logic record counts: 4 Refuse logic record counts: 1 The total time used: 2.030(ms) |
可以看到,只导入了三行,在/home/dmdba/test.bad中查看,内容如下:
dmfldr: 2021-06-17 12:19:09 EZOFFICE->TEST 4 4|aaaa-bbb-ccc |
3.3大字段处理
dmfldr 支持对 DM 数据库的大字段类型数据的载入和导出,DM 数据库支持的大字段
数据类型有 TEXT、LONGVARCHAR、IMAGE、LONGVARBINARY、BLOB 以及 CLOB。
3.3.1大字段数据导出
当 dmfldr 工作在导出模式即 MODE 为 OUT 时,dmfldr 生成大字段对应的数据文件名由LOB_FILE_NAME 指定,若未指定默认为 dmfldr.lob,文件存放于LOB_DIRECTORY 指定的目录,如果未指定 LOB_DIRECTORY 则存放于指定的导出数据文件同一目录。
例如:
- 建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 BLOB,C3 CLOB); |
- 插入数据
INSERT INTO TEST VALUES(1,0XAB121032DE,'abcdefg'); INSERT INTO TEST VALUES(2,0XAB121032DE,'abcdefg'); COMMIT; |
0XAB121032DE是16进制数字,0X表示十六进制。其实可以发现,blob虽然是存储二进制数据的,但是在数据库实际存储的是16进制。如果插入10进制的数字,报错
|
可以使用to_blob函数转换为16进制。
INSERT INTO TEST VALUES(3,to_blob(111111111),'abcdefg'); |
查看实际值:
|
- 编辑控制文件 test.ctrl,存放路径为/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE test FIELDS '|' |
- 导出
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' LOB_DIRECTORY=\'/home/dmdba/\' mode=\'out\' dmfldr V8 2 rows is load out Load finish 2 rows, time:35.958(ms) |
指定了 LOB_DIRECTORY,而没有指定 LOB_FILE_NAME,导出的大字段数据文件将存放在 LOB_DIRECTORY 指定的/home/dmdba目录,文件名为dmfldr.lob
test.txt文件内容如下:
1|dmfldr.lob:0:5|dmfldr.lob:5:7 2|dmfldr.lob:12:5|dmfldr.lob:17:7 |
dmfldr.lob:0:5分别为 文件名:起始偏移:长度。
用strings查看可现实的字符串
[dmdba@localhost ~]$ strings dmfldr.lob abcdefg abcdefg |
用hexdump查看
[dmdba@localhost ~]$ hexdump -C dmfldr.lob 00000000 ab 12 10 32 de 61 62 63 64 65 66 67 ab 12 10 32 |...2.abcdefg...2| 00000010 de 61 62 63 64 65 66 67 |.abcdefg| 00000018 |
对照ASCII值对应十六进制数和字符表可以看到61 62 63 64 65 66 67分别对应abcdefg,32对应2,其他无法显示的用“.”表示。
3.3.2 DIRECT 为TRUE时大字段数据的载入
当 MODE 为 IN 且 DIRECT 为 TRUE 时,此时数据载入若涉及到大字段对象,需要用户指定大字段数据文件。若 CLIENT_LOB 为 TRUE,LOB_DIRECTORY 应指定大字段数据文件所在的客户端本地目录;若 CLIENT_LOB 为 FALSE,用户必须先把相关文件传送到 DM服务器所在主库,然后使用 LOB_DIRECTORY 指明存放目录。
大字段数据文件在数据文件中指定,可以是任意格式的文件。在数据文件中,大字段以
“文件名:起始偏移:长度”的形式记录在数据文件中。指定的文件名无效时,dmfldr 会
报错,装载失败。对于 CLOB 类型字段,当指定的偏移、长度范围内带有不完整字符时,
dmfldr 将装载失败。
例如:
- 建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 BLOB,C3 CLOB); |
- 编辑数据文件 test.txt,存放路径为 DM 服务器所在主库的/home/dmdba/test.txt,文件内容如下:
1|testblob.txt:0:10|testclob.txt:0:10 2|testblob.txt:10:20|testclob.txt:10:20 3|testblob.txt:20:30|testclob.txt:20:30 |
其中,testblob.txt、testclob.txt 为文本文件,长度大于 30 字节,存放路径为/opt/data。比如我建的这两个文件里面内容都是
012345678901234567890123456789 |
- 控制文件如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test FIELDS '|' |
- 装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' LOB_DIRECTORY=\'/home/dmdba/\ |
但是报错:
invalid lob data len |
3.3.3 DIRECT为FALSE时大字段数据的载入
当 MODE 为 IN 且 DIRECT 为 FALSE 时,数据文件中大字段列数据即字段内容。
BLOB_TYPE 参数指定 BLOB 列内容为十六进制或者字符串:
⚫ BLOB_TYPE 为 HEX_CHAR 时,数据文件中BLOB列当作为十六进制内容;
⚫ BLOB_TYPE 为 HEX 时,数据文件中BLOB列为字符串形式内容,导入后会转换为十六进制。
BLOB_TYPE 参数只对 DIRECT 为 FALSE 时有效,默认为 HEX_CHAR。
例1:
- 建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 BLOB,C3 CLOB); |
- 编辑数据文件 test.txt,存放路径为/home/dmdba/test.txt,文件内容如下
1|0x12d3c8a7|abcdefg 2|0x12a4cbac|hijlkmn 3|0x22d3c8b3|adefhjd |
- 编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test FIELDS '|' |
- 载入数据BLOB_TYPE 为 HEX_CHAR
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' direct=false blob_type=\'hex_char\' |
- 查看数据
|
例2:
- 、2)、3)与例1一样。
4)载入数据BLOB_TYPE 为 HEX
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' direct=false blob_type=\'hex\' |
5)查询结果
|
对比两个结果
BLOB | HEX_CHAR | HEX |
0x12D3C8A7 | 0x12D3C8A7 | 0x30783132643363386137 |
可以发现30783132643363386137是“0x12D3C8A7”10个字符对应的16进制的数。
3.4自增列装载--set_identity
自增列是比较特殊的列,为了保证数据库中自增列列值的正确性,用户在进行数据载入
时需要特别注意。
当 DIRECT 参数为 FALSE 时,dmfldr 将把从数据文件中读取的自增列值作为目标值插入数据库表中,用户应当保证每一行的自增列的值符合自增列的规则,否则将造成数据混乱。
当DIRECT参数为TRUE时,dmfldr提供了 SET_IDENTITY 参数(默认为 FALSE)对数据载入时自增列的处理进行设置:
✓ 如果指定 SET_IDENTITY 选项值为 TRUE,则 dmfldr 将把从数据文件中读取的自增列值作为目标值插入数据库表中,用户应当保证每一行的自增列的值符合自增列的规则,否则将造成数据混乱;
✓ 如果 SET_IDENTITY 选项值设置为 FALSE,则 dmfldr 将忽略数据文件中对应
自增列的值,服务器将根据自增列定义和表中已有数据自动生成自增列的值插入每一行的对应列。
例1:
- 建表,插入两行数据
DROP TABLE TEST; CREATE TABLE TEST(C1 INT IDENTITY(1,1),C2 VARCHAR); INSERT INTO TEST(C2) VALUES('AAA'); INSERT INTO TEST(C2) VALUES('BBB'); COMMIT; --此时表数据如下 |
- 编辑数据文件/home/dmdba/test.txt,内容如下:
2|aaa 3|bbb 4|ccc |
- 编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test FIELDS '|' |
- 载入数据
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' direct=true set_identity=false |
- 查看数据
|
可以看到在表 TEST 中已有两行数据的情况下,由于 SET_IDENTITY 置为 FALSE,因此在数据载入时 dmfldr 根据 C1 列的定义和表中已有数据,为 C1 列重新插入合适的值。
例2:
- 、2)、3)与例1一样
4)载入数据
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' direct=true set_identity=true |
5)查看数据
|
可以看到C1列的插入的是2、3、4。在设置自增列的情况下,这明显是不合适的。
3.5数据排序--sorted
SORTED参数用来设置数据是否已经按照聚集索引排序,默认为 FALSE。
如果设置为 TRUE,则用户必须保证数据已按照聚集索引排序完成,并且如果表中存在数据,需要插入的数据索引值要比表中数据的索引值大,服务器在做插入操作时顺序进行插入。
若数据并未按照索引排序,则 dmfldr 会报错,装载失败。如果设置为 FALSE,则服务器对于每条记录进行定位插入。
用户也可以通过设置控制文件中的 OPTIONS 选项来设置 SORTED 的值。SORTED 参数值的优先选择顺序为OPTIONS 选项,参数选项。此参数为可选参数,作用于 MODE 为 IN且 DIRECT 为 TRUE 的情况下,对于其他情况此参数无效。
在数据量大,并且确定数据已按照聚集索引排序完成的情况下,将 SORTED 参数设置
为 TRUE,可以提升装载性能。
例如:
- 建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT CLUSTER PRIMARY KEY,C2 VARCHAR); |
2)编辑数据文件/home/dmdba/test.txt,内容如下:
2|aaa 3|bbb 4|ccc 5|ddd 1|zzz |
3)编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test FIELDS '|' |
4)装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' sorted=true |
由于C1列数据没有按照顺序排列,所有装载失败,报错如下:
can not use nosort option, rows are not sorted |
将test.txt第一列修改为顺序排列,如下:
1|aaa 2|bbb 3|ccc 4|ddd 5|zzz |
重新导入成功。
3.6空值处理--null_mode
dmfldr 通过设置 NULL_MODE 参数来处理空值。
⚫ 设置为 TRUE,载入时 NULL 字符串处理为 NULL,载出时空值处理为 NULL 字符串。
⚫ 设置为 FALSE,载入时 NULL 字符串处理为字符串,载出时空值处理为空串。
例1:
1)建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 VARCHAR); |
2)编辑数据文件/home/dmdba/test.txt,内容如下:
1|aaa 2|NULL 3|null |
3)编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test FIELDS '|' |
4)装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' null_mode=true |
5)查询数据,对C2列使用ifnull函数,如果是空则显示“是空值”
select c1,ifnull(c2,'是空值') from test; |
例2:
1)、2)、3)与例1一样
4)载入数据
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' null_mode=false |
5)查看数据
select c1,ifnull(c2,'是空值') from test; |
3.7条件过滤
通过在控制文件中指定 WHEN <field_conditions>子句,可以在装载过程中对数
据进行过滤,符合 field_conditions 条件的数据才会被装载。
对于条件过滤的使用需注意以下几点:
⚫ 判断条件中的操作符仅支持比较相等和不相等,即=、!=和<>这三个比较操作符;
⚫ 目前仅支持使用 AND 连接多个过滤条件;
⚫ BLANKS 和 WHITESPACE 表示若干个空格;
⚫ 判断条件若使用(p1:p2)作为比较表达式,其意义与在 POSTION 子句中的意义相
同,表示从该行指定位置获取数据进行比较,起始位置和结束位置表示的都是字节位置,包含边界 p1,p2;
⚫ 如果判断条件中使用 colid 作为比较表达式,该列必须在 INTO 表的
coldef_option 中进行说明;
⚫ 如果判断条件中使用 colid 作为比较表达式,判断条件中使用的列仅用于过滤,
并没有对应表中的某个实际列,应在 col_def 中指明 FILLER 属性表示装载时跳
过该列;
⚫ 如果判断条件中比较数据是字符常量值,其长度小于比较表达式长度,则在其之后
补充空格;如果判断条件中比较数据是二进制串常量,其长度小于比较表达式长度,
则在之后补充 0。
1)建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 INT); |
2)编辑数据文件/home/dmdba/test.txt,内容如下:
12 23 32 48 91 |
3)编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE ezoffice.test WHEN C1 != '2' ( C1 position (1:1), C2 position (2:2) ) |
position(p1:p2):从数据文件中每行数据的第 p1 个字节到第 p2 个字节为该列值,包含边界 p1,p2。C1 position (1:1),C2 position (2:2) 即表示C1每行第一个值,C2每行第二个值。
4)装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' |
5)查询数据,可以看到C1=2的行已经被过滤了。
select * from test; |
3.8多表装载
通过在控制文件中指定多个 INTO TABLE 子句,可以将一批数据同时向多个表进行装
载。每个 INTO TABLE 子句中都可以指定 WHEN 过滤条件、FIELDS子句和列定义子句。
对于多表装载的使用需注意以下几点:
⚫ 每个 INTO TABLE 子句的目标表必须是不同的表;
⚫ 多表装载时不支持直接装载分区表子表;
⚫ 对于第二个及其之后的 INTO TABLE 子句,在其 coldef_option 中,必须为第一列指定 POSITION 选项;
1)建表
DROP TABLE TEST1; DROP TABLE TEST2; CREATE TABLE TEST1(C1 INT,C2 INT); CREATE TABLE TEST2(C1 INT,C2 INT); |
2)编辑数据文件/home/dmdba/test.txt,内容如下:
1,2 2,3 3,2 4,8 9,1 |
3)编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE test1 WHEN C1 != '1' FIELDS ',' (c1 position (1:1), c2 ) INTO TABLE test2 WHEN (3:3) = '2' AND c1 != '3' FIELDS ',' ( c1 position (1:1), c2 ) |
WHEN(3:3)与position (3:3)含义相同。即表示每行第三个字符。WHEN (3:3) = '2'即表示C2列不等于2。
4)装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' |
5)查询数据
select * from test1; select * from test2; |
与文档上不同的是,这里C1指定了position,C2没有指定position,C2列都是NULL值,没有显示数字。
C2列也加上position,载入正常。
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE test1 WHEN C1 != '1' FIELDS ',' (c1 position (1:1), c2 position(3:3) ) INTO TABLE test2 WHEN (3:3) = '2' AND c1 != '3' FIELDS ',' ( c1 position (1:1), c2 position (3:3) ) |
3.9个性化设置-skip、load
用户通过设置 dmfldr 的 SKIP、LOAD、ROWS 参数,可以根据自己的需求调整装载的起始行、装载最大行数以及每次提交的行数。
SKIP参数用来设置跳过数据文件起始的逻辑行数,整形数值。默认的跳过起始行数为0 行。如果用户指定了多个文件,且起始文件中的行数不足 SKIP 所指定的行数,则
dmfldr 工具会扫描下一个文件直至累加的行数等于 SKIP 所设置的行数或者所有文件都已扫描结束。
LOAD 参数用来设置装载的最大行数,整形数值。默认的最大装载行数为数据文件中的
所有行数。LOAD 指定的值不包括 SKIP 指定的跳过的行数。
ROWS 参数用来设置每次提交的行数,整形数值。默认的提交行数为 50000 行。提交
行数的值表示提交到服务器的行数,并不一定代表按照数据文件中的数据顺序的行数。用户
可以根据实际情况调整每次提交的行数,以达到性能的最佳点。ROWS 参数作用于 MODE 为IN 的情况下,当 MODE 为 OUT 时无效。
示例:
1)建表
DROP TABLE TEST; CREATE TABLE TEST(C1 INT,C2 VARCHAR); |
2)编辑数据文件/home/dmdba/test.txt,内容如下:
1|aaa 2|bbb 3|ccc 4|ddd 5|eee 6|fff 7|ggg 8|hhh 9|iii 10|jjj |
3)编辑控制文件/home/dmdba/test.ctl,内容如下:
LOAD DATA INFILE '/home/dmdba/test.txt' INTO TABLE test FIELDS '|' ( C1, C2 ) |
4)装载
[dmdba@localhost bin]$ ./dmfldr userid=ezoffice/123456789:5234 control=\'/home/dmdba/test.ctl\' skip=3 load=5 |
即表示从第四行开始导入,加载5行。
5)查询数据
select * from test; |
4.dmfldr优化与限制
4.1 dmfldr主要参数
1)control 控制文件,此参数为必选参数且必须位于参数位置的第二个未知。
2)NULL_STR空值处理,若设置则此参数值将成为数据文件中NULL值的唯一表示方式。区分字符串大小写,并且长度不允许超过128个字节。这个最好设置,不然会报错。具体值可以根据现场来设置。
3)BADFILE记录错误数据的文件路径,字符串类型。默认的错误文件名为fldr.bad。
这个导入的时候必须设置,不然可能丢失数据。导出时不用设置。
4)CHARACTER_CODE数据文件中数据的编码格式,字符串类型。默认为GBK。CHARACTER_CODE的可选项有GBK、GB18080、UTF-8、SINGLE_BYTE和EUC-KR五种。这个必须设置,不然导入的数据可能会出现乱码。
5)ERRORS最大的容错个数,整形数值。默认为100。这个参数可以设置大点,让出错的数据进入到badfile里面,保证第一次有效数据能够完整入库。
4.2影响性能的参数
用户在使用 dmfldr 时根据系统和数据的具体情况对一些参数进行调整,可以获得更
好的性能,手册上面影响性能参数的参数有很多,但是经过多次实践,真正有用的只有BUFFER_NODE_SIZE, READ_ROWS和BDTA_SIZE这三个,其他影响性能的参数默认即可。
1)BUFFER_NODE_SIZE 读取文件缓冲区页大小,值越大,缓冲区的页越大,每次读取的数据就越多,每次发送到服务器的数据也就越多,效率越高。但其大小受dmfldr客户端内存大小限制。
2)READ_ROWS 指定读取缓冲区每次读取的最大行数,整数类型,默认为100000。
实际上取READ_ROWS和BUFFER_NODE_SIZE中较小的值作为一次处理的行数。
3)BDTA_SIZE BDTA(Batch Data)的大小,默认为5000,最大10000。手册中说值越大性能越好,实际上这个值影响性能是个抛物线的形式,具体要根据表结构和数据有关,有时候值越大效率反而越差。对于普通表或者一级分区表,这个值可以适当增大,可以5000-8000测试几轮选择最优值。对于二级分区表,这个值要减少,可以从300-800测试几轮选择最优。
控制文件示例:
OPTIONS ( READ_ROWS = 50000 BUFFER_NODE_SIZE=250 BDTA_SIZE=5000 NULL_STR=' ' ERRORS = 9999999999 ) LOAD DATA INFILE '/datatmp/p01/amfm21_9.csv' badfile '/home/dmdba/ctl/amfm21.bad' append into table amfm21 fields ',' ( BANKID, ACCNO, ACCNAME, ACCNAMB, STSACC, CUSTTYP, CUSTID, ISCHKWH, BRCBLD, ACCSUNU, AVASEQ ) |
4.3 dmfldr限制
dmfldr 的使用存在以下一些限制:
⚫ 不支持向临时表、外部表装载数据
⚫ 不支持向系统表装载数据
⚫ 不支持向带有位图索引的表装载数据
⚫ 不支持向带有函数索引的表装载数据
⚫ 不支持向带有全文索引的表装载数据
⚫ 不支持向 DCP 代理装载数据
⚫ dmfldr 装载时,对约束进行检查,对各种约束的处理机制如下表所示
约束 | 数据不满足时 | 数据插入与否 | 约束是否有效 |
非空约束(NOT NULL) | 报错 | 不插入 | 有效 |
聚集索引(CLUSTER PRIMARY KEY) | 报错 | 不插入 | 有效 |
唯一约束(UNIQUE, PRIMARY KEY) | 报错 | 插入 | 失效 |
引用约束(FOREIGN KEY) | 不报错 | 插入 | 有效 |
CHECK 约束(CHECK) | 不报错 | 插入 | 有效 |
更多资讯请上达梦技术社区了解:https://eco.dameng.com