mysql数据库(一):使用LOAD DATA LOCAL INFILE优化大批量数据导入数据库

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语句

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
MySQL的`LOAD DATA LOCAL INFILE`命令中,当导入数据时,MySQL会根据数据文件中的内容来进行数据类型推断。如果数据文件中的某一列被解释为整数类型,而实际上该列包含了字符串数据(如VARCHAR类型),那么MySQL会尝试将该列转换为整数类型。 这种情况下,可能是由于数据文件中的某些行中的数据不符合该列定义的数据类型,导致了自动转换错误。MySQL会根据一些规则进行自动转换,例如将非数字字符转换为0或忽略该行数据。 为了避免这种情况,你可以在`LOAD DATA LOCAL INFILE`命令中明确指定每列的数据类型,而不依赖于自动推断。使用`FIELDS TERMINATED BY`和`LINES TERMINATED BY`来指定字段和行的分隔符,并使用`SET`关键字来指定每列的数据类型。 例如,假设你有一个包含字符串的CSV文件(以逗号分隔),其中一列应该是VARCHAR类型。你可以使用以下命令来导入数据并明确指定数据类型: ```sql LOAD DATA LOCAL INFILE 'data.csv' INTO TABLE your_table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (column1, @var1, column3) SET column2 = CAST(@var1 AS VARCHAR(255)); ``` 在上面的命令中,我们使用了一个用户变量`@var1`来临时存储数据,并使用`CAST`函数将其转换为VARCHAR类型,并将其赋给目标列`column2`。 通过明确指定每列的数据类型,你可以确保导入数据时不会发生意外的类型转换。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踩踩踩从踩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值