CSVとJSONはおそらくあなたが開発者として遭遇する最も一般的な2つのデータフォーマットです。 CSVファイルはスプレッドシートのエクスポート、データベースダンプ、データサイエンスパイプラインに現れます。 JSONはウェブのあらゆるところにあります — REST API、設定ファイル、NoSQLデータベース。どちらもプレーンテキストで、 どちらも人間が読め、どちらも仕事をこなせます。しかし、異なるデータの形のために構築されており、 間違った方を選ぶと本当の頭痛の種になります。この記事では、コアの違いを紹介し、 各フォーマットが輝く(そして崩壊する)具体的な例を示し、 それらを選ぶための実用的な意思決定ガイドを提供します。

根本的な違い:テーブル対ツリー

CSV — RFC 4180で定義 — はフラットな表形式のフォーマットです。すべての行が同じ列を持ち、すべての値が文字列です。 それだけです。スプレッドシートやデータベーステーブルに完全にマッピングされます:行は縦、列は横。

JSON — RFC 8259で指定され、 json.orgで説明 — は階層的なフォーマットです。値はオブジェクト、配列、文字列、数値、ブール値、またはnullになれます。 オブジェクトがオブジェクト内にネストされ、配列は混合した形を持てます。データが実際にコード内でどう存在するかにマッピングされます — 関係を持つレコード、異なるもののリスト、型付き値。

一行サマリー:CSVはテーブルです。JSONはツリーです。データがテーブルなら、CSVはシンプルで小さい。 データに何らかのネストがあれば、CSVは情報を失うかまたは痛みを伴う回避策を強いるかのどちらかです。

両フォーマットで同じデータを見る

ここで違いが具体的になります。Eコマースストアの商品カタログを想像してください。 商品には名前、価格、在庫状況があります — 単純です。しかしバリアント(サイズ、色)と 属性(素材、重量)もあります。そのデータが両フォーマットでどう見えるか見てみましょう。

JSONではこれは自然です:

json
[
  {
    "id": "SHOE-001",
    "name": "Trail Runner Pro",
    "price": 129.99,
    "inStock": true,
    "attributes": {
      "material": "mesh",
      "weightGrams": 280
    },
    "variants": [
      { "size": 9,  "color": "black", "sku": "TR-9-BLK",  "qty": 12 },
      { "size": 9,  "color": "white", "sku": "TR-9-WHT",  "qty": 4  },
      { "size": 10, "color": "black", "sku": "TR-10-BLK", "qty": 7  }
    ]
  },
  {
    "id": "SHOE-002",
    "name": "City Walker",
    "price": 89.99,
    "inStock": true,
    "attributes": {
      "material": "leather",
      "weightGrams": 340
    },
    "variants": [
      { "size": 8,  "color": "brown", "sku": "CW-8-BRN",  "qty": 6  },
      { "size": 9,  "color": "brown", "sku": "CW-9-BRN",  "qty": 15 }
    ]
  }
]

それをCSVに入れようとすると。2つの選択肢があり、どちらも不便です。 選択肢1:すべてを平坦化して各バリアント行に親データを繰り返す:

csv
product_id,product_name,price,inStock,material,weightGrams,variant_size,variant_color,sku,qty
SHOE-001,Trail Runner Pro,129.99,true,mesh,280,9,black,TR-9-BLK,12
SHOE-001,Trail Runner Pro,129.99,true,mesh,280,9,white,TR-9-WHT,4
SHOE-001,Trail Runner Pro,129.99,true,mesh,280,10,black,TR-10-BLK,7
SHOE-002,City Walker,89.99,true,leather,340,8,brown,CW-8-BRN,6
SHOE-002,City Walker,89.99,true,leather,340,9,brown,CW-9-BRN,15

商品名、価格、属性が各バリアントに繰り返されています。それはデータの冗長性です — 5行では大したことではありませんが、各8バリアントを持つ50,000商品のカタログでは積み重なります。 選択肢2:バリアントをCSV列内のJSON文字列としてシリアライズする — しかし今やCSVの限界を回避するために CSVの中にJSONを埋め込んでいます。これはコードの臭いです。

CSVが勝つ場所

その限界にもかかわらず、CSVはいくつかの一般的なシナリオで真に優れた選択です。

  • スプレッドシートとBIツール。Excel、Google Sheets、Tableau、Looker、Power BI — すべてワンクリックでCSVをネイティブに開きます。インポートウィザードなし、定義するスキーマなし、変換ステップなし。ステークホルダーがスプレッドシートで生活しているなら、CSVは最も抵抗が少ない道です。
  • 純粋にフラットなデータ。データが本当にテーブル — 分析イベント、トランザクションログ、センサー読み取り、ユーザーエクスポート — なら、CSVは小さくシンプルです。繰り返しのキーなし、括弧なし、ノイズなし。
  • データベースのインポート/エクスポート。すべてのSQLデータベースにCOPY FROM CSVコマンドまたは同等のものがあります。これは一括データ読み込みの標準的な交換フォーマットであり、INSERTステートメントよりも何桁も速いです。
  • pandasとデータサイエンス。pandas.read_csv()はPythonデータワークで最も使われる関数の一つです。エコシステム全体 — NumPy、scikit-learn、Polars — はCSVを第一級の入力フォーマットとして扱います。
  • 大きなフラットテーブルのファイルサイズ。各行にキー名がなければ、CSVは多くの行を持つ幅広いテーブルに対してより小さいです。100万行の分析イベントのCSVは、同等のJSON配列を楽に上回ります。

JSONが勝つ場所

  • ネストされた階層的データ。データにフラットテーブルを超えた構造がある瞬間 — ネストされたオブジェクト、異なる形の配列、関連するレコード — JSONはそれを自然に処理します。CSVは情報を失うか冗長性を作るかせずにこれを表現できません。
  • 型の保持。CSVではすべてが文字列です。true42null、そして"true"はすべて同じに見えます。受信側で型を推論する必要があり、それがバグにつながります。JSONにはネイティブのブール値、数値、nullがあります。inStock: trueは明確にブール値です — 推測は不要。
  • REST APIとウェブ。JSONはウェブのネイティブデータフォーマットです。すべてのHTTPクライアントライブラリ、すべてのブラウザのFetch API、すべてのRESTとGraphQL APIはJSONを話します。HTTPでCSVを送信することは可能ですが珍しいです — 両端でカスタム解析が必要になります。
  • NoSQLデータベース。MongoDB、DynamoDB、Firestore、Elasticsearch、CouchDB — すべてJSONをネイティブドキュメントフォーマットとして使用します(またはBSONのようなバイナリスーパーセット)。JSONを書けばJSONが返ってきます。
  • 設定ファイル。package.jsontsconfig.jsonmanifest.json — ツール設定はJSONに標準化されています。なぜならネスト構造をサポートし、プログラム的に生成・検証が容易だからです。
  • スキーマ検証。JSON Schemaでドキュメントの正確な形を定義し、データを検証できます — 型チェック、必須フィールド、パターンマッチング、配列制約。CSVには同等の標準がありません。

ファイルサイズ:本当の話

「CSVの方が小さい」という主張は1つの特定のケースで真です:多くの行を持つ大きなフラットテーブル。 8つの固定フィールドを持つ100,000の分析イベントを取ってください。CSVでは、フィールド名はヘッダーに一度現れます。 JSONでは、すべてのオブジェクトに現れます。その繰り返しが積み重なります — JSON配列は 同等のCSVよりも30〜50%大きくなる可能性があります。

しかしシナリオをネストされたデータに反転させると数学が変わります。靴カタログの平坦化されたCSVは 各バリアント行に商品名、価格、属性を繰り返します。JSONバージョンは各商品を一度格納します。 多くの親フィールドが繰り返される深くネストされたデータでは、JSONは実際にはより小さいことがあります。

実際には、ファイルサイズが本当の懸念事項なら、両フォーマットともgzipで非常によく圧縮されます — JSONの繰り返しのキー名とCSVの繰り返しの行値はどちらも強く圧縮されます。HTTPでgzip圧縮されたJSONを提供することは 標準的な実践であり、圧縮後のサイズの差は通常無視できるほど小さくなります。

ツールの比較

各フォーマットのツールの話は、最も使われる場所を反映しています。

CSVツール:Excel、Google Sheets、LibreOffice CalcはネイティブにCSVを開きます。 pandasライブラリはCSVをPythonデータ分析の デフォルトにしています。すべてのリレーショナルデータベースにCSVインポート/エクスポートコマンドがあります。 csvkitxsvのようなコマンドラインツールでコードを書かずにCSVファイルをフィルタリング、 結合、集計できます。MIMEタイプはtext/csvでIANAに登録されています。

JSONツール:すべてのプログラミング言語に組み込みまたは標準ライブラリのJSONパーサーがあります。 JavaScriptのJSON.parse()、Pythonのjson.loads()、Goのencoding/json、 Rustのserde_jsonMDNのJSON参照は MDNで最も訪問されるページの一つです。コマンドライン:jqはJSONのクエリと変換に不可欠です。 IDEは自動的に整形・検証します。

両方の世界にまたがるデータパイプラインで作業している場合 — JSON APIレスポンスをデータウェアハウスに ロードしたり、データベースレコードをスプレッドシート用にエクスポートしたり — 定期的に変換することになります。 CSVからJSONコンバーターJSONからCSVコンバーターがそれを素早く処理します。 処理前に生ファイルを整理するには、CSVフォーマッターJSONフォーマッターをブックマークする価値があります。

ハイブリッド:JSON Lines (NDJSON)

知っておく価値がある3番目の選択肢があります:JSON Lines、NDJSONとも呼ばれます (改行区切りJSON)。アイデアはシンプルです — 1行につき1つの完全なJSONオブジェクト、周囲の配列なし。

json
{"id":"SHOE-001","name":"Trail Runner Pro","price":129.99,"inStock":true,"variantCount":3}
{"id":"SHOE-002","name":"City Walker","price":89.99,"inStock":true,"variantCount":2}
{"id":"SHOE-003","name":"Summit Hiker","price":159.99,"inStock":false,"variantCount":5}

このフォーマットは特定のユースケースで両方の良いところを提供します。CSVのように、ファイル全体を メモリにロードせずに行ごとにストリーミングして処理できます — 大きなログファイルやデータパイプライン出力に重要です。 JSONのように、各行が異なるスキーマを持て、型を保持します。標準のUnixツール(grepwc -lhead) で作業できますが、構造化クエリのために各行をjqにパイプすることもできます。

NDJSONはログ集約(多くの構造化ロガーのデフォルト出力フォーマット)、データパイプラインステージ、 ML訓練データエクスポートに広く使われています。何百万ものレコードを処理するスクリプトを書いており、各レコードが JSONオブジェクトなら、NDJSONは通常巨大なJSON配列より正しい選択です — すべてをメモリにロードすることを避け、 チェックポイントから簡単に再開できます。

python
import json

# Process a large NDJSON file without loading it all into memory
with open('products.ndjson', 'r') as f:
    for line in f:
        product = json.loads(line.strip())
        if product['inStock'] and product['price'] < 100:
            print(f"{product['name']} — ${product['price']}")

意思決定ガイド:CSV対JSON

これが実用的なバージョンです。2つの間で選択するとき、自分にこれらの質問をしてください:

  • データは本当にフラット(ネストなし、配列なし)ですか?そうなら、CSVがよりシンプルです。そうでなければ、JSON。
  • 非開発者がこのファイルを消費しますか?Excelのアナリスト?Google Sheetsのビジネスユーザー?CSVを使う。
  • HTTP APIを提供または消費していますか?JSONを使う。完全に。
  • データベースの一括インポートまたはエクスポートを行っていますか?CSVを使う — すべてのデータベースがネイティブにサポートしています。
  • データに混合型(ブール値、数値、null)がありますか?受信側の型推論バグを避けるためにJSONを使う。
  • ファイルがストリーミングパイプラインで行ごとに処理されますか?中間的選択肢としてNDJSONを検討する。
  • 設定を格納していますか?JSONを使う(またはコメントが重要なら YAML)。
  • スキーマがレコードごとに変わる必要がありますか?JSON。CSVはすべての行に同じ列を強制します。
正直なデフォルト:他の開発者や機械が消費するものを構築しているなら、JSONを使う。 スプレッドシートで開く人間にデータを渡すなら、CSVを使う。何百万もの構造化レコードを処理する データパイプラインを構築しているなら、NDJSONを検討する。

まとめ

CSVとJSONは本当に競合していません — 異なる問題を解決します。CSVはデータがテーブルで、 スプレッドシートとデータベースツールとの最大限の互換性が欲しい場合の正しいツールです。 JSONはデータに構造、型、またはネストがあり、APIやアプリケーションと話している場合の正しいツールです。

決定は通常、データの実際の形を見ると難しくありません。センサー読み取りのフラットな行?CSV。 ネストされたユーザープロファイルと埋め込まれた注文履歴を持つAPIレスポンス?JSON。 構造化イベントのストリーミングログ?NDJSON。フォーマットをデータの形と両端のツールに合わせれば、 ほとんど間違えることはありません。