shell脚本实践 (二):ftp下载文件到本地并直接入mysql库
前言
我之前有一篇通过ftp下载文件到本地到mysql数据库中,使用LOAD DATA LOCAL INFILE 导入txt数据到数据库中,所以也研究了下这个关键字的关键点。
使用LOAD DATA LOCAL INFILE 导入txt数据到数据库中,可以提高从文件中导入数据到数据库效率,并且降低服务器内存使用,提高效率的作用

首先

LOAD DATA
    [LOW_PRIORITY | CONCURRENT] [LOCAL]
    INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT}
        [, col_name={expr | DEFAULT}] ...]

LOAD DATA语句以非常高的速度将行从文本文件读取到表中。可以从服务器主机还是客户端主机读取文件,具体取决于是否指定了LOCAL修饰符。 LOCAL还影响数据解释和错误处理。
LOAD DATA是的补充 SELECT … INTO OUTFILE,都是为了优化大数据量从文本转入数据库中

LOW_PRIORITY | CONCURRENT

低优先级|同时发生的
使用该LOW_PRIORITY修饰符,该LOAD DATA语句的执行被延迟,直到没有其他客户端从表中读取为止。这会影响只使用表级锁只存储引擎(例如MyISAM,MEMORY和MERGE)。也就是说使用该关键字,如果其他客户端访问,则会被延迟。
使用CONCURRENT修饰符和一个MyISAM满足并发插入条件的 表(即,中间不包含空闲块),其他线程可以在LOAD DATA执行时从表中检索数据 。LOAD DATA即使没有其他线程同时使用该表,此修饰符也会影响代码的性能。

LOCAL

非本地与本地操作
该LOCAL修改影响的 LOAD DATA这些方面,相比于非LOCAL操作:
1.它更改了输入文件的预期位置
LOCAL指定,则文件必须位于客户端主机上。客户端程序读取文件,如下所示定位它,
如果文件名是绝对路径名,则客户端程序将使用给定的名称。
如果文件名是相对路径名,则客户端程序将查找相​​对于其调用目录的文件。
当LOCAL使用时,客户端程序读取该文件,并将其内容的服务器。服务器在存储临时文件的目录中创建文件的副本。 该目录中副本的足够空间不足会导致 LOAD DATA LOCAL语句失败。
2.它更改了语句的安全性要求
LOAD DATA LOCAL的安全注意事项
因为在服务端 默认情况下,它local_infile 是禁用的 ,,服务器会拒绝或允许请求本地数据加载的客户端加载本地数据。 所以有loose-local-infile=0 loose-local-infile=1
安全要求
对于非LOCAL加载操作,服务器读取位于服务器主机上的文本文件
1.必须具有FILE 特权。
2.该操作取决于 secure_file_priv系统变量设置
如果变量值为非空目录名,则文件必须位于该目录中。
如果变量值为空(不安全),则文件仅需要服务器读取。最好设置

 在LOCAL 关键字中可以访问所有的地址

REPLACE | IGNORE

重复键和错误处理
在REPLACE与IGNORE 修饰符控制处理的那个唯一键值 ,
使用REPLACE,与现有行中的唯一键值具有相同值的新行将替换现有行
使用IGNORE,将删除在唯一键值上复制现有行的新行。
该LOCAL剂具有相同的效果 IGNORE。发生这种情况是因为服务器在操作过程中没有办法停止文件的传输。
如果没有REPLACE, IGNORE或者LOCAL指定,当找到一个重复的键值发生错误,并且文本文件的余下部分被忽略。
使用IGNORE或LOCAL,即使SQL模式是限制性的,数据解释错误也将成为警告,并且装入操作将继续

PARTITION (partition_name [, partition_name] …)

LOAD DATA支持使用带PARTITION 子句的显式分区选择,该子句包含一个或多个以逗号分隔的分区名,子分区名或两者的列表。使用此子句时,如果无法将文件中的任何行插入列表中命名的任何分区或子分区中,则该语句将失败,并显示错误“找到与给定分区集不匹配的行”。

5.CHARACTER SET charset_name

默认情况下,服务器使用character_set_database系统变量指示的字符集解释文件内容 。 LOAD DATA将文件中的所有字段解释为具有相同的字符集,而不管字段值加载到的列的数据类型如何。

6.FIELDS LINES

FIELDS和LINES子句的语法 相同。这两个子句都是可选的,但 如果同时指定了两个子句,则 FIELDS必须在LINES它们之前。
如果指定一个FIELDS子句,则每个子句(TERMINATED BY, [OPTIONALLY] ENCLOSED BY和 ESCAPED BY)也是可选的,但必须至少指定其中一个。这些子句的参数只能包含ASCII字符。
必须将两个反斜杠指定为将值解释为单个反斜杠。转义序列’\t’ 和分别’\n’指定制表符和换行符。
换句话说,默认值导致LOAD DATA在读取输入时的行为如下:
在换行符处查找行边界。
不要跳过任何行前缀。
在选项卡上将行分成字段。
不要期望将字段括在任何引号中。
将转义字符前面的字符解释 \为转义序列。例如, \t,\n,和 \,则意味着制表符,换行符和反斜杠,分别。有关FIELDS ESCAPED BY转义序列的完整列表,请参见后面的讨论。

如果所有输入行都有您要忽略的公共前缀,则可以使用跳过该前缀以及该前缀之前的所有内容。如果一行不包含前缀,则会跳过整行。假设您发出以下语句: LINES STARTING BY ‘prefix_string’

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
  FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';

如果数据文件如下所示:

xxx"abc",1
something xxx"def",2
"ghi",3

结果行为(“abc”,1)和 (“def”,2)。文件中的第三行被跳过,因为它不包含前缀。
可以结合起来使用

IGNORE number {LINES | ROWS}

该子句可用于忽略文件开头的行。例如,可以用来跳过包含列名称的初始标题行: IGNORE number LINESIGNORE 1 LINES

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

SET col_name={expr | DEFAULT}

LOAD DATA INFILE ‘persondata.txt’ INTO TABLE persondata
(col_name_or_user_var [, col_name_or_user_var] …);
如果输入文件中字段的顺序与表中列的顺序不同,则还必须指定一个列列表。否则,MySQL无法告知如何将输入字段与表列匹配。

总的来说

LOAD DATA LOCAL INFILE 是相当强大的,不仅提供了很多关键字给我们使用,提高我们的效率,特别是针对大数据量导入是非常快的,能根据各自的项目需求选择使用

如果想学习非常深入,还是的看官方文档
LOAD DATA语句

还有另外一篇是针对批量导出数据的
SELECT … INTO语句

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐