在开发和运维中,经常需要在 SQLite 和 MySQL 之间导入导出数据。本篇总结这两个数据库系统的常用导入导出命令,涵盖整库和单表操作,适用于备份、迁移和初始化场景。
一、SQLite3 命令详解
导出整个数据库为 SQL 文件
sqlite3 data.db .dump > backup.sql
data.db是数据库文件名;.dump会导出数据库结构 + 全部数据;- 生成的
backup.sql可用.read或<命令导入。
导出单个表为 SQL 文件
sqlite3 data.db ".dump users" > users.sql
只导出 users 表的数据和结构。
导入 SQL 文件到 SQLite 数据库
sqlite3 data.db < backup.sql
或者交互模式下:
sqlite3 data.db
sqlite> .read backup.sql
导出为 CSV 文件
sqlite3 data.db
sqlite> .headers on
sqlite> .mode csv
sqlite> .output users.csv
sqlite> SELECT * FROM users;
说明:
.headers on:写出表头;.mode csv:设置导出为 CSV 格式;.output:指定输出文件;SELECT:执行查询写入文件。
从 CSV 导入数据
sqlite3 data.db
sqlite> .mode csv
sqlite> .import --skip 1 users.csv users
两个必须知道的点:
- 目标表必须已存在,
.import不会替你建表; --skip 1不能省。CSV 第一行通常是表头(id,name,email),不跳过的话 这行会被当成一条真实数据插进去,之后查出来会多一条id等于字符串"id"的脏记录——不报错,所以很容易一直没发现。
旧版本 sqlite3 没有 --skip 参数,那就先把表头行删掉再导。
二、MySQL 命令详解
导出整个数据库
mysqldump -u root -p --single-transaction mydb > backup.sql
参数说明:
| 参数 | 含义 | 不加会怎样 |
|---|---|---|
-u root |
用户名 | — |
-p |
提示输入密码 | 密码写在命令行里会进 shell 历史,也会被 ps 看到 |
--single-transaction |
用一致性快照导出,不锁表 | InnoDB 表在导出期间被锁住,线上写不进去 |
mydb |
要导出的数据库名 | — |
--single-transaction 只对 InnoDB 有效,MyISAM 表还是会被锁。
导出单个表
mysqldump -u root -p mydb users > users.sql
只导出 users 表的数据和结构。
导入 SQL 文件到 MySQL
mysql -u root -p mydb < backup.sql
或在交互模式中执行:
mysql -u root -p
mysql> USE mydb;
mysql> SOURCE /path/to/file.sql;
导出表为 CSV(仅限服务器路径)
SELECT * FROM users
INTO OUTFILE '/tmp/users.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
这条经常直接报 The MySQL server is running with the --secure-file-priv option。
原因是 MySQL 限定了只能读写某一个目录,先查出来是哪个:
SHOW VARIABLES LIKE 'secure_file_priv';
- 返回一个路径:只能往这个目录里写,
/tmp多半不行; - 返回空:不限制;
- 返回
NULL:功能被彻底禁用,INTO OUTFILE用不了。
另外文件是 MySQL 服务进程写的,落在服务器上而不是你的电脑上。想直接导到本地, 改用客户端来做:
mysql -u root -p -e "SELECT * FROM users" mydb | sed 's/\t/,/g' > users.csv
从 CSV 导入数据
LOAD DATA INFILE '/tmp/users.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES; -- 跳过表头,和 SQLite 的 --skip 1 是一回事
文件在你本地而不是服务器上,就得加 LOCAL:
LOAD DATA LOCAL INFILE '/home/me/users.csv' INTO TABLE users ...
LOCAL 需要服务端和客户端都打开 local_infile(SET GLOBAL local_infile=1,
客户端加 --local-infile=1),MySQL 8 默认是关的。
三、总结对比表
| 操作 | SQLite3 | MySQL |
|---|---|---|
| 导出整库 | .dump > file.sql |
mysqldump db > file.sql |
| 导出单表 | .dump table |
mysqldump db table > file.sql |
| 导入 SQL | .read file.sql / < file.sql |
mysql db < file.sql |
| 导出 CSV | .mode csv + SELECT |
SELECT INTO OUTFILE |
| 导入 CSV | .import file.csv table(需预建表) |
LOAD DATA INFILE(需服务端路径权限) |
这些命令覆盖了日常开发中常见的数据库迁移、表结构导出、数据备份等任务场景,建议熟练掌握并结合脚本使用。