MySQL LOAD DATA与INSERT导入大批量数据示例代码
作者:一号IT男
前言
LOAD DATA
是 MySQL 中一个非常强大且高效的指令,用于将文本文件(如 CSV、TSV)的内容快速批量地读入到数据库表中。相比于使用多个 INSERT
语句,它在处理大量数据时速度要快几个数量级。
核心功能
它的核心功能就是:将服务器主机上的一个文本文件,高速地导入到指定的数据库表中。
基本语法
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'] -- 行结束符,例如 '\n' 或 '\r\n' ] [IGNORE number {LINES | ROWS}] -- 忽略文件开头的几行(如标题行) [(col_name_or_user_var [, col_name_or_user_var] ...)] [SET col_name = expr [, col_name = expr] ...]
关键参数详解
LOCAL
- 有 LOCAL:客户端命令。文件位于客户端主机上(即你执行 mysql 命令的机器)。文件内容会通过客户端连接发送到服务器。安全性稍低,因为服务器无法控制客户端文件。
- 无 LOCAL:服务器端命令。文件必须位于服务器主机上,并且运行 MySQL 服务的用户(通常是
mysql
)必须有读取该文件的权限。这种方式更快,但需要直接访问服务器文件系统。
INFILE 'file_name'
- 指定源文件的路径。对于服务器端加载,路径可以是绝对路径或相对路径(相对於
secure_file_priv
系统变量指定的目录)。
- 指定源文件的路径。对于服务器端加载,路径可以是绝对路径或相对路径(相对於
INTO TABLE tbl_name
- 指定目标表的名字。
FIELDS 子句 (定义每个字段的格式)
TERMINATED BY
:字段之间的分隔符。常见的有','
(CSV),'\t'
(制表符,TSV),'|'
等。ENCLOSED BY
:字段的包围符。常用'"'
。如果使用OPTIONALLY
,则只用于字符串类型的字段。ESCAPED BY
:转义字符。默认是反斜杠\
。用于转义特殊字符,例如字段中包含分隔符时。
LINES 子句 (定义每行的格式)
TERMINATED BY
:行的结束符。在 Windows 上创建的文件通常是'\r\n'
,在 Linux/macOS 上是'\n'
。现代 MySQL 通常能自动处理。STARTING BY
:行的开始符,很少使用。
IGNORE number LINES
- 极其常用。用于跳过文件开头的
number
行。例如,如果文本文件第一行是列标题(如id,name,age
),则使用IGNORE 1 LINES
来跳过它。
- 极其常用。用于跳过文件开头的
REPLACE 和 IGNORE
- REPLACE:如果导入的数据与表中现有记录的主键 (Primary Key) 或唯一索引 (Unique Index) 冲突,则用新数据替换掉原有数据。
- IGNORE:(默认行为)如果发生冲突,则忽略(丢弃)当前导入的行,并继续处理下一行。
- 如果两者都不指定,冲突会导致错误,并停止导入。
CHARACTER SET
- 指定文件的字符编码。如果文件编码与数据库默认编码不同,必须指定。例如,处理中文时如果遇到乱码,可能需要设置
CHARACTER SET utf8mb4
。
- 指定文件的字符编码。如果文件编码与数据库默认编码不同,必须指定。例如,处理中文时如果遇到乱码,可能需要设置
列映射 (col_name, ...) 和 SET
- 可以在语句最后指定一个列列表,例如
(col1, col2, col3)
。这会告诉 MySQL 文件中的数据按此顺序对应到这些列。表的其他列将被设置为默认值。 - 如果文件中的列顺序与表结构不同,或者你需要对数据进行一些简单的转换,这个功能就非常有用。
SET
子句可以用于对列进行表达式计算。例如,如果文件中有日期字符串,你可以用SET date_column = STR_TO_DATE(@var_date, '%Y-%m-%d')
来转换格式。
- 可以在语句最后指定一个列列表,例如
工作流程与示例
假设场景:
我们有一个 employees
表:
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(100), department VARCHAR(100), salary DECIMAL(10, 2), hire_date DATE );
还有一个 employees_data.csv
文件,内容如下:
id,name,department,salary,hire_date 105,'Alice Smith','Engineering',75000,'2022-03-15' 106,'Bob Johnson','Marketing',65000,'2021-11-01' 107,'Charlie Lee','Sales',NULL,'2023-01-20' -- 注意:salary是NULL
目标: 将此 CSV 文件导入到 employees
表中。
步骤 1:处理文件
确保文件格式正确,分隔符为逗号,字符串用单引号包围(MySQL 默认期望双引号,所以我们需要指定),第一行是标题。
步骤 2:执行 LOAD DATA 语句
LOAD DATA LOCAL INFILE '/path/to/your/employees_data.csv' INTO TABLE employees -- 定义格式:字段用逗号分隔,字符串用单引号包围 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\'' -- 忽略第一行标题 IGNORE 1 LINES -- 明确指定列名(顺序和文件中的列顺序一致) (id, name, department, salary, hire_date);
注意: 如果字符串包围符是双引号 "
,则只需写 ENCLOSED BY '"'
。
重要注意事项与最佳实践
secure_file_priv 系统变量:
- 这是 MySQL 的一个安全限制。如果设置了此变量(通常默认是设置的),
LOAD DATA
只能读写该变量指定目录下的文件。 - 使用
SHOW VARIABLES LIKE 'secure_file_priv';
查看其值。 - 对于无 LOCAL 的加载,文件必须放在这个目录下。
- 对于有 LOCAL 的加载,此变量不适用。
- 这是 MySQL 的一个安全限制。如果设置了此变量(通常默认是设置的),
性能:
- 在导入前禁用索引(特别是唯一索引)可以极大提升速度。导入完成后再重建索引。
ALTER TABLE tbl_name DISABLE KEYS; -- 执行 LOAD DATA ... ALTER TABLE tbl_name ENABLE KEYS;
- 使用事务:将
LOAD DATA
包装在一个事务中,要么全部成功,要么全部失败。
START TRANSACTION; LOAD DATA ...; COMMIT;
错误处理:
- 仔细检查
FIELDS
和LINES
的配置是否与文件格式完全匹配,一个字符的差别都可能导致整个导入失败或数据错乱。 - 首次导入时,可以先用一个小的样本文件进行测试。
- 仔细检查
NULL 值处理:
- 在文件中,
NULL
值应该用\N
(反斜杠加大写 N)表示。如果你的文件里是空字符串或者NULL
这个词,可能需要使用SET
子句进行转换,例如SET salary = NULLIF(@var_salary, '')
。
- 在文件中,
与INSERT的对比
特性 | LOAD DATA | INSERT 语句 |
---|---|---|
速度 | 极快,是批量操作 | 慢,逐行或小批量操作 |
网络开销 | 有 LOCAL 时较大(传输文件) | 非常大(传输每条SQL) |
功能 | 丰富的数据格式处理选项 | 灵活,可包含复杂逻辑和函数 |
适用场景 | 初始化数据、数据迁移、批量导入 | 应用程序的日常操作、单条插入 |
总结: LOAD DATA INFILE
是 MySQL 数据导入的“王牌工具”,专门为高速批量数据处理而设计。只要熟练掌握其语法和选项,它就能成为你数据库管理工作中不可或缺的利器。
总结
到此这篇关于MySQL LOAD DATA与INSERT导入大批量数据的文章就介绍到这了,更多相关MySQL导入大批量数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!