如何将非CSV格式的ASCII数据导入SQLite 3?
解决SQLite .import导入含特殊字符大文本数据的问题
我之前也处理过类似的超大数据量导入需求,你的思路完全正确——用SQLite支持的ASCII格式(自定义分隔符)确实是避开CSV引号/逗号问题的最优解,报错的核心原因是没有正确配置分隔符变量,导致SQLite还是按默认CSV规则解析数据,自然识别不出列分隔。
下面是一步步的落地解决方法:
1. 确认SQLite版本要求
首先确保你的SQLite版本≥3.16.0(2017年1月发布),因为.rowseparator命令是这个版本才引入的,低版本不支持自定义行分隔符。可以用sqlite3 --version查看版本,不够的话建议升级,毕竟4亿行数据的导入效率也和版本密切相关。
2. 准备符合格式的数据
按照你的需求,把数据处理成以下规则:
- 列与列之间用**ASCII 31(0x1F,单位分隔符)**分隔
- 每条记录(行)之间用**ASCII 30(0x1E,记录分隔符)**分隔
- 不需要给字段加任何引号,也不用处理内部的逗号、引号、制表符,只要确保数据本身不包含0x1F和0x1E这两个字符(如果有的话,预处理替换成其他字符即可)
比如你的样本数据处理后,用十六进制表示的二进制格式是:
6170706C651F612066727569741F6E6F20226F746865722220636F6D6D656E74732C20666F72206E6F771E67726170651F616E6F746865722066727569741F5965732C2049206C696B65206772617065731E
在Linux/macOS下可以用printf快速生成测试数据文件:
printf 'apple\x1Fa fruit\x1Fno "other" comments, for now\x1Egrape\x1Fanother fruit\x1FYes, I like grapes\x1E' > test_data.txt
3. 执行导入操作
打开SQLite shell,按以下步骤操作:
第一步:创建目标表
sqlite3 your_database.db CREATE TABLE testtable ( item char(20), descr char(30), misc char(40) );
第二步:开启事务(关键优化,提升4亿行导入速度)
BEGIN TRANSACTION;
第三步:设置分隔符
.separator \x1F -- 列分隔符:ASCII 31(0x1F) .rowseparator \x1E -- 行分隔符:ASCII 30(0x1E)
第四步:执行导入(指定ascii格式)
.import --ascii test_data.txt testtable
第五步:提交事务
COMMIT;
4. 验证导入结果
执行查询确认数据是否正确导入:
SELECT * FROM testtable;
你会看到每条记录的字段都被正确拆分,包含逗号、双引号的字段也完全保留,没有被错误解析。
额外优化建议(针对4亿行数据)
为了避免导入耗时过长,还可以添加以下优化:
- 关闭同步:
PRAGMA synchronous = OFF;(牺牲一点安全性换速度,导入完成后可以改回默认) - 关闭外键约束:
PRAGMA foreign_keys = OFF;(导入完成后再开启) - 禁用索引:如果表有索引,可以先删除,导入完成后再重建,大幅减少写入时间
内容的提问来源于stack exchange,提问作者algn2
相关产品推荐
相关产品推荐

