暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

CSV “Comma-Separated Values”

恩恩霸 2025-09-16
549

CSV 格式介绍

一、CSV 是什么
CSV 是 “Comma-Separated Values”(逗号分隔值)的缩写,是一种**纯文本**、**行式**、**字段分隔**的表格数据存储格式。它既不含数据类型信息,也不含样式、公式、宏等高级特性,仅把一张二维表用最简方式落盘:一行就是一条记录,一行内用指定分隔符(最常见是半角逗号 ,)把字段隔开。因其极简、通用、易读、易写,被几乎所有电子表格(Excel、WPS、Numbers)、数据库(PostgreSQL、MySQL、Oracle、SQL Server)、编程语言(Python、R、Java、C/C++、Go、Rust、JavaScript)以及 ETL、BI、大数据平台(Hadoop、Spark、Flink、Pandas)原生支持,成为“数据交换领域的最低公约数”。

二、历史渊源
CSV 的雏形可追溯到 1972 年 IBM Fortran 编译器提供的“列表定向输入输出”(list-directed I/O),那时用逗号或空格分隔数值。1978 年,美国国家标准局发布《磁带交换格式》(ANS X3.27-1978),首次把“逗号分隔”写进官方文档。1983 年,PC/MS-DOS 下的 Lotus 1-2-3 把 CSV 作为“导出无格式数据”的选项,从此进入桌面用户视野。1995 年,IETF 发布《RFC 4180 “Common Format and MIME Type for CSV Files”》,首次尝试统一方言,奠定现代 CSV 的语法骨架。2005 年以后,随着开源运动与大数据崛起,CSV 成为 GitHub、Kaggle、data.gov、UNData 等开放数据平台的首选分发格式,至今仍是“最大公约数”。

三、语法规则(RFC 4180 精简版)
1. 文件由可选标题行与零到多条记录行组成,行终止符为 CRLF(\r\n),也容忍 LF(\n)。
2. 每条记录含一个或多个字段,字段间以逗号分隔。
3. 字段内若出现分隔符、换行、双引号,则整个字段必须用双引号括起来。
4. 字段内的双引号用两个连续双引号转义("")。
5. 文件编码无强制要求,但 UTF-8 已成为事实标准;Windows 世界仍常见 GBK/CP936。
6. 大小写敏感、前后空格均保留,解析端自行决定 trim 与否。
7. 无显式 NULL 字面量;空串 "" 与 NULL 的语义由业务层约定。

四、方言多样性
虽然 RFC 4180 给出“官方”模板,但现实世界里“CSV”早已泛化为“**任意分隔**”的统称:
- 分隔符:逗号(,)、分号(;)、制表符(\t,即 TSV)、竖线(|)、 caret(^)、SOH(\x01,Hive 默认)。
- 引号符:双引号(")、单引号(')、无引号。
- 转义符:双写引号("")、反斜杠(\")、反斜杠转义(\,)。
- 编码:UTF-8、UTF-8-BOM、GB18030、Shift-JIS、Latin-1。
- 行尾:CRLF、LF、CR。
- 标题行:有或无。
- 注释行:#、--、//。
- 数字千分位:12,345.67 可能把逗号当成分隔符,导致错位。
因此生产环境必须显式指定 dialect,否则极易“看上去解析成功,实则字段错位”。

五、与二进制格式的对比
优点:
1. 人类可读,用 cat/less/vim/notepad 即可预览。
2. 版本无关,1970 年的文件今天仍能打开。
3. 压缩友好,重复字符多,gzip/brotli/zstd 压缩比高。
4. 语言绑定零成本,标准库即可完成读写。
缺点:
1. 无数据类型,"00123" 是字符串还是整数需要外部元数据。
2. 无约束信息,无法声明“主键、非空、枚举值”。
3. 编码、分隔、转义方言多,互换成本高。
4. 大文件(TB 级)按行扫描效率低,无法随机定位某列。
5. 二进制数据(图片、音频、浮点 NaN)需先 base64,体积膨胀。

六、在 PostgreSQL 中的落地
PostgreSQL 提供 COPY table TO 'file.csv' WITH (FORMAT csv, HEADER true, DELIMITER ',', QUOTE '"', ESCAPE '"', ENCODING 'UTF8'),一条命令即可把整表导出成标准 CSV;反向 COPY table FROM 'file.csv' … 可并行高速导入。内部实现采用批量流式读写,单核即可达 200 MB/s,搭配 gzip 管道可直接落盘压缩文件。对于超宽表(上千列),CSV 的文本优势尤为明显,比 SQL 插入脚本节省 5–10 倍体积。

七、性能优化技巧
1. 导入前暂时 drop 索引、触发器、外键,导入后重建,可减少随机写。
2. 使用 COPY … FROM PROGRAM 'zstd -cd file.csv.zst' 边解压边导入,省临时磁盘。
3. 设置 synchronous_commit = off、wal_level = minimal、maintenance_work_mem = 2GB,可提升 3–5 倍。
4. 对超大表分段并行:split -l 1000w file.csv | xargs -P 4 -I{} psql -c "\copy table from '{}' csv header"。
5. 利用 pg_bulkload、timescaledb-parallel-copy 等工具,绕开 WAL,时速可达 3000 万行以上。

八、常见陷阱与排查
1. 编码炸弹:Windows 生成 GBK 文件,Linux 按 UTF-8 导入,导致“invalid byte sequence for encoding UTF8”。解决:iconv -f gbk -t utf-8 file.csv -o file_utf8.csv。
2. 分隔符歧义:地址字段含逗号,未用引号包围,结果列数变多,COPY 报 “extra data after last expected column”。解决:前置清洗,或改用制表符分隔。
3. 换行符灾难:Mac 旧版 CR(\r)被识别为单行,导致整文件被当成一行。解决:dos2unix 或 sed $'s/\r/\n/g'。
4. 引号未转义:字段值 She said "Hello" 直接写成双引号,导致解析器以为字段提前结束。解决:She said ""Hello""。
5. 空串与 NULL 混淆:业务要求 \N 代表 NULL,但 COPY 默认把空串当空串。解决:COPY … WITH NULL '\N'。

九、安全与合规
CSV 本身无执行能力,相较 .sql 脚本更安全;但仍需防范:
- 公式注入:Excel 打开 CSV 时,以 =、+、-、@ 开头的字段会被当成公式,可能导致命令执行(DDE)或超链接跳转。敏感数据导出前加制表符 't 前缀。
- 隐私泄露:导出前脱敏(hash、掩码、泛化),或采用列级加密。
- 文件权限:COPY TO 文件时,确保目录权限 700,防止其他用户读走。
- 上传校验:Web 端接受 CSV 上传后,先放隔离区,用杀毒软件扫描,防止“带有恶意宏的 CSV 伪装器”。

十、未来趋势
1. 压缩 CSV:CSV.gz、CSV.zst、CSV.br 已成为 BigQuery、Redshift、Snowflake 外部表的标准后缀,透明解压。
2. 列式 CSV:Apache Arrow 提出 “CSV-like” 中间层,把行式 CSV 流式转成列式 ArrowRecordBatch,兼顾易读与高性能。
3. 类型化 CSV:Frictional CSV、CSV Schema、CSV on the Web(W3C)尝试用 sidecar JSON-LD 描述列类型、约束,实现“自描述 CSV”。
4. 流式增量:Kafka Connect、Debezium 把变更事件编码为 CSV 流,供 Flink 实时计算。
5. 云原生:AWS S3 Select、Azure Data Lake、Google Cloud Storage 均已支持 “SQL on CSV” 服务端过滤,无需下载整文件即可 SELECT 所需列。

十一、结语
CSV 没有华丽的技术光环,却凭借“最小功能集 + 最大兼容性”穿越半个世纪,从 Fortran 磁带走到云数据湖。它像一把瑞士军刀:简单到任何人都能徒手编辑,又强大到足以承载 TB 级别数据管道。理解其规则、方言、陷阱与优化,是每一位数据工程师、DBA、开发者的基本功。只要人类还在用二维表表达数据,CSV 就不会退场——它将继续在服务器、U 盘、邮件附件、对象存储、数据仓库之间默默流动,成为数字世界的“最低共识协议”。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论