大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解

embedded/2025/3/10 22:31:41/

一.问题背景

        java项目基于sql>mysql实现大数据表跨服务器导入导出功能。之前整理过百万数据导入内存溢出的解决方案,这次情况又不一样了, 21万包含longtext字段的数据导入导出,解决了内存溢出的问题,速度却很慢,即使开启批量插入,sql解析也需要耗费很长时间。经过一番查阅资料,使用sql>mysql的load data infile/select into outfile命令直接操作csv文件,可以很好的解决大数据表导入导出的效率问题。


二.解决方案

1.load data infile/select into outfile命令

(1)简单导入导出sql

sql">-- 导出csv
SELECT * INTO OUTFILE '绝对路径.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM table_name;-- 导入csv
LOAD DATA INFILE '绝对路径.csv' into table table_name FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';

注意:如果用Navicat执行命令,发现导出成功但找不到文件,或者明明目录存在却报错找不到指定路径,是因为sql>mysql默认加载路径为sql>mysql服务器路径,指定 LOCAL 可加载客户端文件。

(2)详细语法

sql">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}] ...]

参考官网:
https://dev.sql>mysql.com/doc/refman/8.0/en/load-data.html

2.变量secure-file-priv设置

        使用以上命令做导入导出操作时,通常会遇到The MySQL server is running with the --secure-file-priv option so it cannot execute this statement报错,原因是执行此命令的文件所在的路径不在sql>mysql配置的指定范围内,通过改变系统变量secure-file-priv的值,可以变更可操作的文件范围。
        secure-file-priv变量是只读的,不能通过set命令设置,需要修改sql>mysql的配置文件my.ini或my.cnf,重启sql>mysql服务生效。

(1)secure-file-priv变量值查询

sql">SHOW VARIABLES LIKE 'secure_file_priv';

(2)secure-file-priv变量值设置

(3)secure_file_priv可以设置如下:

设置值操作范围备注
可以操作所有文件不安全。服务器在启动时检查secure_file_priv的值,如果该值不安全,则将警告写入错误日志。
绝对路径该目录下的文件可执行导入导出操作服务器不会自动创建目录,设置的目录必须存在。若目录不存在,服务器会将错误消息写入错误日志并退出。
NULL禁用导入和导出操作

参考官网:
https://dev.sql>mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv

三.权限及环境问题

1.权限问题

        执行导入导出命令出现Can't create/write to file '/var/lib/myFile.csv' (OS errno 13 - Permission denied)报错,是目录操作权限不足。可直接通过命令赋予权限,或通过代码赋予权限。

java代码段

java">String osName = System.getProperty("os.name").toLowerCase();if (osName.contains("win")) {log.info("当前操作系统是Windows");File ff = new File(outPath);ff.setReadable(true, false); // 设置文件可读权限ff.setWritable(true, false); // 设置文件可写权限ff.setExecutable(true, false); // 设置文件可执行权限} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {// 这里的"nix"可以匹配Linux,"nux"可以匹配Solaris,"aix"可以匹配AIXlog.info("当前操作系统是Linux");Set<PosixFilePermission> permissions = new HashSet<>();permissions.add(PosixFilePermission.OWNER_READ);permissions.add(PosixFilePermission.OWNER_WRITE);permissions.add(PosixFilePermission.OWNER_EXECUTE);permissions.add(PosixFilePermission.GROUP_READ);permissions.add(PosixFilePermission.GROUP_WRITE);permissions.add(PosixFilePermission.GROUP_EXECUTE);permissions.add(PosixFilePermission.OTHERS_READ);permissions.add(PosixFilePermission.OTHERS_WRITE);permissions.add(PosixFilePermission.OTHERS_EXECUTE);Files.setPosixFilePermissions(Paths.get(outPath), permissions);} else {log.info("无法识别的操作系统: " + osName);}
2.环境问题

        踩过以上坑之后,Linux环境不出意外可以顺利进行导入导出了。此处Windows环境还需注意一点,路径不能用单反斜杠\,需要转换为双反斜杠\\ 或 斜杠/。单反斜杠会被转义掉,变成文件名,如下图所示。

sql示例

sql">-- 不能按指定路径导出文件
SELECT * INTO OUTFILE 'C:\Users\user\Desktop\demo\table_name.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM table_name;-- 可以按指定路径导出文件
SELECT * INTO OUTFILE 'C:\\Users\\user\\Desktop\\demo\\table_name.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM table_name;-- 可以按指定路径导出文件
SELECT * INTO OUTFILE 'C:/Users/user/Desktop/demo/table_name.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM table_name;

至此,问题解决。

以上为个人观点,仅供学习记录,欢迎交流讨论。


http://www.ppmy.cn/embedded/171594.html

相关文章

【每日八股】Golang篇(二):关键字(上)

目录 make 和 new 的区别&#xff1f;概念例子 struct 能不能比较&#xff1f;为什么 slice 之间不能直接比较&#xff1f;slice 的底层实现&#xff1f;slice 和数组的区别&#xff1f;slice 的扩容机制&#xff1f;slice 是线程安全的吗&#xff1f;slice 之间如何比较&#…

PY32MD320单片机 QFN32封装,内置多功能三相 NN 型预驱。

PY32MD320单片机是普冉半导体的一款电机专用MCU&#xff0c;芯片采用了高性能的 32 位 ARM Cortex-M0 内核&#xff0c;主要用于电机控制。PY32MD320嵌入高达 64 KB Flash 和 8 KB SRAM 存储器&#xff0c;最高工作频率 48 MHz。PY32MD320单片机的工作温度范围为 -40 ~ 105 ℃&…

华为欧拉系统 Tomcat 安装详解

1. 安装或确认安装 Java Tomcat 需要 Java 环境(JDK 或 JRE)才能运行。如果系统尚未安装 Java,可以使用以下命令安装 OpenJDK: # 更新软件包索引 yum update -y# 安装 OpenJDK 21(可根据需求安装其他版本,如 8、11、17 等) yum install -y java-21-openjdk java-21-op…

python软件开发安装包配置问题以及如何焕电脑后批量安装安装包的问题

1.在软件开发的过程中往往需要安装许多的python包&#xff0c;如果通过&#xff1a;通过pip install packagex.x.x指定特定版本的话容易出现漏装的情况&#xff0c;于是就需要找到指定包进行安装&#xff0c;但这个时候如果我们新建一个文本文档&#xff1a;requirements&#…

C# 基础知识总结(持续更新中...)

C#有哪些数据类型&#xff1f; 值类型 引用类型 整数类型 实数类型 布尔类型 字符类型 结构类型 枚举类型 类 数组 字符串 接口 委托 对象型 C#有哪几种访问修饰符&#xff0c;有何区别&#xff1f; public 公共成员 访问不受限制 private 私有成员 只限于当前类成员…

计算机网络(1) 网络通信基础,协议介绍,通信框架

网络结构模式 C/S-----客户端和服务器 B/S -----浏览器服务器 MAC地址 每一个网卡都拥有独一无二的48位串行号&#xff0c;也即MAC地址&#xff0c;也叫做物理地址、硬件地址或者是局域网地址 MAC地址表示为12个16进制数 如00-16-EA-AE-3C-40 &#xff08;每一个数可以用四个…

【JavaWeb学习Day22】

后端开发原理 配置的优先级 Springboot中支持三种格式的配置文件&#xff1a;&#xff08;以及优先级&#xff09; &#xff08;注意&#xff1a;虽然springboot支持多种格式的配置文件&#xff0c;但是在项目开发时&#xff0c;推荐统一使用一种格式的配置&#xff0c;yml是…

Python Flask框架学习汇编

1、总览&#xff1a; 《Flask 全栈学习指南》 2、入门级&#xff1a; 《Python Flask Web 框架入门》 这篇博文条理清晰&#xff0c;由简入繁&#xff0c;案例丰富&#xff0c;分十五节详细讲解了Flask框架&#xff0c;强烈推荐&#xff01; 《python的简单web框架flask【…