把 CSV 文件导入数据库听起来很简单,实操时却要手写 INSERT 语句、猜字段类型,还要处理 MySQL、PostgreSQL、SQLite 之间的方言差异。本文系统梳理 CSV 转 SQL 的每个环节,也可以直接用 CSV 转 SQL 在线工具 跳过手动步骤。
CSV 转 SQL 会生成什么
CSV 文件由两部分组成:定义列名的表头行,以及存放数据的数据行。转换为 SQL 会生成:
- 声明列名和类型的
CREATE TABLE语句。 - 批量写入数据的
INSERT INTO语句。
给定如下 CSV:
id,name,email,age,active
1,张伟,[email protected],30,true
2,李芳,[email protected],25,false
转换结果:
CREATE TABLE data (
id INTEGER,
name TEXT,
email TEXT,
age INTEGER,
active BOOLEAN
);
INSERT INTO data (id, name, email, age, active) VALUES
(1, '张伟', '[email protected]', 30, TRUE),
(2, '李芳', '[email protected]', 25, FALSE);
表头处理
CSV 第一行默认为表头,会成为 SQL 的列名。规范的工具会做以下清洗:
- 将空格和特殊字符替换为下划线(
订单日期→订单日期,order date→order_date) - 统一小写,保持命名一致
- 避免使用 SQL 保留字作列名(如
order改为order_col)
如果 CSV 没有表头行,工具应提供数字列名(col1、col2……)或允许手动输入列名。
字段类型推断
自动类型推断扫描每列所有值,选择最合适的 SQL 类型:
| 检测到的模式 | SQL 类型 |
|---|---|
| 全部为整数 | INTEGER |
| 含小数 | FLOAT / NUMERIC |
全为 true/false(不区分大小写) | BOOLEAN |
符合 ISO 8601 日期(2024-01-15) | DATE |
| 符合 ISO 8601 日期时间 | TIMESTAMP |
| 混合或无法解析 | TEXT / VARCHAR |
类型推断是尽力而为:只有某列每个非空单元格都是整数,才会推断为 INTEGER;一旦出现非数字值,就回退到 TEXT。
方言差异
MySQL
MySQL 用 INT 而非 INTEGER,保留字标识符需要反引号,旧版本用 TINYINT(1) 表示布尔。
CREATE TABLE `users` (
`id` INT,
`name` VARCHAR(255),
`active` TINYINT(1)
);
PostgreSQL
PostgreSQL 类型严格。自增主键用 SERIAL 或 BIGSERIAL,布尔字面量为 TRUE/FALSE,文本列默认 TEXT 无长度限制。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
active BOOLEAN
);
SQLite
SQLite 使用动态类型,支持 INTEGER、REAL、TEXT、BLOB、NUMERIC。没有原生布尔类型,用 INTEGER 的 0/1 代替。列宽声明会被忽略,VARCHAR(255) 和 TEXT 等价。
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
active INTEGER
);
常见 CSV 问题处理
带引号的字段 — 用双引号包裹的字段可以包含逗号和换行,正确的解析器会将 "张伟, 工程师" 视为一个字段而非两个。
缺失值 — 空单元格在 SQL 中应生成 NULL,而非空字符串。
大文件 — 批量 INSERT 比逐行语句性能好得多。工具应将多行合并:
INSERT INTO data (id, name) VALUES
(1, '张伟'),
(2, '李芳'),
(3, '王磊');
编码问题 — Excel 导出的 CSV 常用 GBK 或 Windows-1252 编码,出现乱码时先将文件另存为 UTF-8 再导入。
数字形式的字符串 — 邮政编码、手机号、商品编码看起来是数字,但应保存为 TEXT。检测到前导零(010-8888)或特定格式(+86-13800138000)时不应推断为数值类型。
使用 zerotool.dev CSV 转 SQL 工具
- 打开 zerotool.dev/tools/csv-to-sql。
- 粘贴 CSV 内容或上传文件。
- 选择目标方言:MySQL、PostgreSQL 或 SQLite。
- 核查检测到的列类型——可以在生成前手动覆盖。
- 复制
CREATE TABLE和INSERT INTO语句,在数据库客户端执行。
转换完全在浏览器本地完成,数据不会上传到任何服务器。
什么时候只用 INSERT 不用 CREATE TABLE
如果目标表已经存在,跳过 CREATE TABLE 只运行 INSERT INTO 即可。大多数工具支持单独切换。从零新建表时,两者都需要生成。
百万级别以上的数据量,建议用数据库原生的批量加载工具代替 INSERT 语句:
- MySQL:
LOAD DATA INFILE - PostgreSQL:
COPY FROM - SQLite:CLI 中的
.import命令
几百到几千行数据直接用生成的 SQL 即可。
相关工具
- CSV 转 JSON — 将 CSV 转为 JSON 数组
- CSV 转 Markdown — 将表格数据转为 Markdown 表格
- JSON 格式化 — 验证并美化 JSON