把 CSV 文件导入数据库听起来很简单,实操时却要手写 INSERT 语句、猜字段类型,还要处理 MySQL、PostgreSQL、SQLite 之间的方言差异。本文系统梳理 CSV 转 SQL 的每个环节,也可以直接用 CSV 转 SQL 在线工具 跳过手动步骤。

CSV 转 SQL 会生成什么

CSV 文件由两部分组成:定义列名的表头行,以及存放数据的数据行。转换为 SQL 会生成:

  1. 声明列名和类型的 CREATE TABLE 语句。
  2. 批量写入数据的 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 dateorder_date
  • 统一小写,保持命名一致
  • 避免使用 SQL 保留字作列名(如 order 改为 order_col

如果 CSV 没有表头行,工具应提供数字列名(col1col2……)或允许手动输入列名。

字段类型推断

自动类型推断扫描每列所有值,选择最合适的 SQL 类型:

检测到的模式SQL 类型
全部为整数INTEGER
含小数FLOAT / NUMERIC
全为 true/false(不区分大小写)BOOLEAN
符合 ISO 8601 日期(2024-01-15DATE
符合 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 类型严格。自增主键用 SERIALBIGSERIAL,布尔字面量为 TRUE/FALSE,文本列默认 TEXT 无长度限制。

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT,
  active BOOLEAN
);

SQLite

SQLite 使用动态类型,支持 INTEGERREALTEXTBLOBNUMERIC。没有原生布尔类型,用 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 工具

  1. 打开 zerotool.dev/tools/csv-to-sql
  2. 粘贴 CSV 内容或上传文件。
  3. 选择目标方言:MySQL、PostgreSQL 或 SQLite。
  4. 核查检测到的列类型——可以在生成前手动覆盖。
  5. 复制 CREATE TABLEINSERT INTO 语句,在数据库客户端执行。

转换完全在浏览器本地完成,数据不会上传到任何服务器。

什么时候只用 INSERT 不用 CREATE TABLE

如果目标表已经存在,跳过 CREATE TABLE 只运行 INSERT INTO 即可。大多数工具支持单独切换。从零新建表时,两者都需要生成。

百万级别以上的数据量,建议用数据库原生的批量加载工具代替 INSERT 语句:

  • MySQL:LOAD DATA INFILE
  • PostgreSQL:COPY FROM
  • SQLite:CLI 中的 .import 命令

几百到几千行数据直接用生成的 SQL 即可。

相关工具

立即使用 CSV 转 SQL 工具 →