CSV vs TSV vs JSON — どのデータ交換フォーマットを選ぶべきか
Excel エクスポート・API レスポンス・ETL パイプラインで使う 3 種類のフォーマットを、構造表現力・パース容易性・ツール互換で比較。CSV エスケープ地獄や JSON のサイズ膨張も整理します。
どの軸で選ぶか — 構造・区切り・互換性
データ交換フォーマットを選ぶとき、判断軸はだいたい 4 つです。構造表現力 はフラットな表で足りるのか、ネストした階層を持たせる必要があるのかを決めます。区切り文字とエスケープの煩雑さ はパーサ実装の難易度と「データ自体に区切り文字が混ざったとき」の壊れやすさを左右します。互換性 は受け側 (Excel / プログラミング言語の標準ライブラリ / SaaS の import 画面) によって急に厳しくなります。型情報 は数値・真偽値・null を区別したいかどうか、文字列として扱われると困らないかです。
「CSV はレガシー」「JSON が現代の正解」のような単線比較では決まりません。Excel に貼り付けて目視確認したい運用に JSON を使うと逆に手間が増えますし、API レスポンスに CSV を使うとネスト構造を表現するために独自規約を増やすことになります。配布先と「次に何をするか」で軸の重みが変わるだけです。
3 フォーマットの比較表
| 項目 | CSV | TSV | JSON |
|---|---|---|---|
| 構造 | フラット (2 次元の表) | フラット (2 次元の表) | 階層 (オブジェクト・配列・ネスト) |
| 区切り | カンマ , | タブ \t | 構文 ({}, [], :, ,) |
| エスケープ | ダブルクオート " で囲み、内部の " は "" に二重化 | 原則エスケープ無し (タブ・改行を含めない運用) | バックスラッシュ \ (\", \n, \u00XX 等) |
| 改行を含むセル | 引用符で囲めば可 (実装によって扱いが揺れる) | 想定されていない | 文字列内 \n で安全に表現 |
| 型 | すべて文字列 (数値判定は受け側) | すべて文字列 | string / number / boolean / null / object / array |
| 標準仕様 | RFC 4180 (2005) | IANA text/tab-separated-values | RFC 8259 (2017) / ECMA-404 |
| MIME タイプ | text/csv | text/tab-separated-values | application/json |
| Excel との相性 | ◯ (ただし UTF-8 BOM 問題あり) | ◎ (コピペが安全) | △ (Power Query 経由) |
| 文字コード | 実運用は UTF-8 + BOM か Shift_JIS | 同左 | UTF-8 が事実上唯一 |
CSV の悩みどころはほぼ エスケープ に集約されます。たとえば「Hello, “world”」という 1 セルを書くと "Hello, ""world""" となり、引用符の数を間違えるとパーサが残りの行をまるごと壊します。さらに Excel が UTF-8 CSV を Shift_JIS と誤判定して日本語が文字化けする問題は、BOM (EF BB BF) を先頭に付けるか、Excel 側の「データ取得」ウィザードで明示するかで回避します。TSV はそもそもセル内に改行・タブを含めない前提なので、エスケープ規則が薄く、機械生成のログやスクリプトの出力との相性がよい代わりに「タブを含む自然言語データ」には不向きです。JSON は階層と型を素直に表現できますが、人間が縦列で目視比較したいデータには冗長で、サイズも CSV の 1.5〜2 倍程度になりがちです。
用途別の落としどころ
Excel で開いて目視確認したい・人間が編集する: CSV。csv-encoding-convert で UTF-8 BOM 付きに整えれば Excel での文字化けは防げます。日本語を含む場合は特に BOM の有無が分かれ目になります。
スクリプトの出力をコピペで貼り付ける・タブで列が揃う表として読みたい: TSV。セパレータがカンマと違って自然な日本語文に含まれにくく、引用符のエスケープも基本不要なので、ログ整形やワンライナーで作る出力に向きます。Slack や GitHub Issue へそのまま貼ると等幅で整います。
API レスポンス・設定ファイル・ネストしたデータ: JSON。配列の中にオブジェクト、その中にさらに配列、というツリーを自然に書けるのは JSON だけです。型 (true/false/null/数値) が文字列と区別されるので、受け側のバリデーションも書きやすくなります。
バックエンド間の大量データ転送: CSV または TSV (圧縮前提)。1 行 = 1 レコードのストリーム処理に向き、gzip で 10-20% 程度まで縮みます。JSON は同じデータでもキー名が毎行繰り返されるので、サイズと帯域では不利になります。
Excel から取り出して別システムへ流す中継: TSV。Excel の選択範囲をコピーするとクリップボードに TSV が入るので、変換せずそのままパースできます。
ブラウザだけで相互変換と文字コード調整
フォーマットの選択が決まっても、実データは別形式で渡ってくることがほとんどです。csv-json-convert は CSV と JSON を相互変換し、ヘッダー行の扱いや配列の階層化方針を指定できます。Excel が読めない UTF-8 CSV を渡されたときや、Shift_JIS の古いシステムへ流すために変換したいときは csv-encoding-convert で BOM の付与・除去や文字コード変換ができます。どちらも入力ファイルはブラウザ内で TextDecoder / TextEncoder を使って処理しており、サーバーへアップロードする経路がコードに存在しません。
注意点は エスケープが壊れた CSV の救出は難しい ことです。引用符のバランスが崩れた CSV をそのまま JSON 化すると、行の境界がズレて以降のデータが全部 1 セル下にシフトすることがあります。先にテキストエディタで該当行を目で確認するか、csv-stats のような検査ツールで行・列数の異常を見つけてから変換するのが安全です。実装は GitHub で公開しており、DevTools の Network タブで「変換中にどこへも送信されていない」ことを目視確認できます。