CSV og JSON er sandsynligvis de to mest almindelige dataformater du støder på som udvikler. CSV-filer dukker op i regnearkseksporter, database-dumps og datavidenskabs-pipelines. JSON er overalt på nettet — REST API'er, konfigurationsfiler, NoSQL-databaser. Begge er ren tekst, begge er menneskelæselige, og begge udfører jobbet. Men de er bygget til forskellige dataformer, og at vælge den forkerte skaber reelle problemer. Denne artikel gennemgår de centrale forskelle, viser dig konkrete eksempler på hvor hvert format brillerer (og bryder ned), og giver dig en praktisk beslutningsguide til at vælge imellem dem.

Den centrale forskel: tabeller vs træer

CSV — defineret i RFC 4180 — er et fladt, tabelformat. Hver række har de samme kolonner, enhver værdi er en streng. Det er alt. Det mapper perfekt til et regneark eller en databasetabel: rækker ned, kolonner på tværs.

JSON — specificeret i RFC 8259 og beskrevet på json.org — er et hierarkisk format. Værdier kan være objekter, arrays, strenge, tal, booleaner eller null. Objekter er indlejret i objekter, arrays holder blandede former. Det mapper til hvordan data faktisk lever i kode — poster med relationer, lister over forskellige ting, typede værdier.

Ettlinjes sammenfatning: CSV er en tabel. JSON er et træ. Hvis dine data er en tabel er CSV enklere og mindre. Hvis dine data har nogen indlejring vil CSV enten miste information eller tvinge dig til smertefulde omgåelser.

De samme data i begge formater

Her bliver forskellen konkret. Forestil dig et produktkatalog for en e-handelsbutik. Produkter har et navn, pris og om de er på lager — ligetil. Men de har også varianter (størrelser, farver) og attributter (materiale, vægt). Lad os se hvordan de data ser ud i begge formater.

I JSON er dette naturligt:

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 }
    ]
  }
]

Prøv nu at lægge det i en CSV. Du har to muligheder, begge besværlige. Mulighed et: flat alt ud og gentag forælderdata for hvert variantrækken:

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

Produktnavnet, prisen og attributterne gentages for hvert variant. Det er dataredundans — ikke en stor sag for fem rækker, men for et katalog med 50.000 produkter med 8 varianter hver, summerer det op. Mulighed to: serialiser varianterne som en JSON-streng inden i en CSV-kolonne — men nu indlejrer du JSON inde i CSV for at omgå CSVs begrænsninger, hvilket er en code smell hvis der nogensinde var en.

Hvor CSV vinder

På trods af denne begrænsning er CSV genuint det bedre valg i adskillige almindelige scenarier.

  • Regneark og BI-værktøjer. Excel, Google Sheets, Tableau, Looker, Power BI — de åbner alle CSV nativt med ét klik. Ingen importguide, intet skema at definere, intet transformationstrin. Hvis dine interessenter lever i regneark er CSV vejen med mindst modstand.
  • Rent flade data. Hvis dine data genuint er en tabel — analysehændelser, transaktionslogfiler, sensoraflæsninger, brugereksport — er CSV mindre og enklere. Ingen gentagne nøgler, ingen parenteser, ingen støj.
  • Databaseimport/-eksport. Enhver SQL-database har en COPY FROM CSV-kommando eller tilsvarende. Det er standardudvekslingsformatet for massedata-indlæsning og er størrelsesordener hurtigere end INSERT-sætninger.
  • pandas og datavidenskab. pandas.read_csv() er en af de mest brugte funktioner i Python-dataarbejde. Hele økosystemet — NumPy, scikit-learn, Polars — behandler CSV som et førsteklasses inputformat.
  • Filstørrelse til store flade tabeller. Uden nøglenavne på hver række er CSV mindre for brede tabeller med mange rækker. En million-rækkers CSV med analysehændelser vil komfortabelt slå det ækvivalente JSON-array.

Hvor JSON vinder

  • Indlejret og hierarkisk data. Så snart dine data har nogen struktur ud over en flad tabel — indlejrede objekter, arrays af forskellige former, relaterede poster — håndterer JSON det naturligt. CSV kan ikke repræsentere dette uden at miste information eller skabe redundans.
  • Typebevarelse. I CSV er alt en streng. true, 42, null og "true" ser alle ens ud. Du skal udlede typer på modtagersiden, hvilket fører til fejl. JSON har native booleaner, tal og null. inStock: true er utvetydigt en boolean — ingen gætning nødvendig.
  • REST API'er og nettet. JSON er nettets native dataformat. Ethvert HTTP-klientbibliotek, enhver browsers Fetch API, enhver REST og GraphQL API taler JSON. At sende CSV over HTTP er muligt men usædvanligt — du ville have brug for tilpasset parsing i begge ender.
  • NoSQL-databaser. MongoDB, DynamoDB, Firestore, Elasticsearch, CouchDB — alle bruger JSON (eller et binært supersæt som BSON) som deres native dokumentformat. Du skriver JSON ind, du får JSON tilbage.
  • Konfigurationsfiler. package.json, tsconfig.json, manifest.json — værktøjskonfiguration har standardiseret på JSON fordi det understøtter indlejrede strukturer og er let at programmatisk generere og validere.
  • Skemavalidering. JSON Schema lader dig definere den præcise form af et dokument og validere data imod det — typekontroller, påkrævede felter, mønstermatchning, arraybegrænsninger. CSV har ingen tilsvarende standard.

Filstørrelse: den virkelige historie

Påstanden "CSV er mindre" er sand i ét specifikt tilfælde: store flade tabeller med mange rækker. Tag 100.000 analysehændelser, hver med otte faste felter. I CSV vises feltnavnene én gang i headeren. I JSON vises de på hvert objekt. Den gentagelse summer op — JSON-arrayet kan være 30–50% større end det ækvivalente CSV.

Men vend scenariet til indlejrede data og matematikken ændrer sig. Det fladede CSV af vores skokatalog gentager produktnavnet, prisen og attributterne på hver variantrække. JSON-versionen gemmer hvert produkt én gang. For dybt indlejrede data med mange gentagne forælderfelter kan JSON faktisk være mindre.

I praksis, hvis filstørrelse er et reelt problem, komprimerer begge formater ekstremt godt med gzip — de gentagne nøglenavne i JSON og gentagne rækkeværdier i CSV komprimerer begge kraftigt. At servere gzippet JSON over HTTP er standardpraksis, og størrelsesforskellen bliver normalt ubetydelig efter komprimering.

Sammenligning af værktøjer

Værktøjshistorien for hvert format afspejler hvor det bruges mest.

CSV-værktøjer: Excel, Google Sheets og LibreOffice Calc åbner det nativt. Biblioteket pandas gør CSV til standard for dataanalyse i Python. Enhver relationsdatabase har en CSV-import/-eksportkommando. Kommandolinjeværktøjer som csvkit og xsv lader dig filtrere, sammenføje og aggregere CSV-filer uden at skrive kode. MIME-typen er text/csv, registreret hos IANA.

JSON-værktøjer: hvert programmeringssprog har en indbygget eller standardbiblioteks-JSON-parser. JSON.parse() i JavaScript, json.loads() i Python, encoding/json i Go, serde_json i Rust. MDN JSON-referencen er en af de mest besøgte sider på MDN. Kommandolinje: jq er uundværlig til at forespørge og transformere JSON. IDE'er smukkeetryk og validerer det automatisk.

Hvis du arbejder med datapipelines der spænder over begge verdener — indlæsning af JSON API-svar til et datalager, eller eksport af databaseposter til et regneark — konverterer du regelmæssigt mellem de to. Konverteren CSV til JSON og JSON til CSV håndterer det hurtigt. Til oprydning af råfiler inden behandling er CSV Formatter og JSON Formatter værd at bogmærke.

Hybriden: JSON Lines (NDJSON)

Der er en tredje mulighed der er værd at kende: JSON Lines, også kaldet NDJSON (Newline-Delimited JSON). Ideen er enkel — et komplet JSON-objekt per linje, uden omgivende array.

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}

Dette format giver dig det bedste fra begge verdener til visse brugstilfælde. Som CSV kan du streame og behandle det linje for linje uden at indlæse hele filen i hukommelsen — kritisk for store logfiler eller datapipeline-output. Som JSON kan hver linje have et andet skema og bevarer typer. Du kan bruge standard Unix-værktøjer (grep, wc -l, head) til at arbejde med det, men også pipe hver linje gennem jq til strukturerede forespørgsler.

NDJSON bruges bredt til logaggregering (det er standardoutputformatet for mange strukturerede loggere), datapipeline-faser og ML-træningsdataeksporter. Hvis du skriver et script der behandler millioner af poster og hver post er et JSON-objekt, er NDJSON normalt det rigtige valg frem for et kæmpe JSON-array — du undgår at indlæse det hele i hukommelsen og kan nemt fortsætte fra et kontrolpunkt.

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']}")

Beslutningsguide: CSV vs JSON

Her er den praktiske version. Når du vælger mellem de to, still dig disse spørgsmål:

  • Er dine data genuint flade (ingen indlejring, ingen arrays)? Hvis ja, er CSV enklere. Hvis nej, JSON.
  • Vil en ikke-udvikler forbruge denne fil? Analytikere i Excel? Erhvervsbrugere i Google Sheets? Brug CSV.
  • Serverer eller forbruger du et HTTP API? Brug JSON. Fuld stop.
  • Foretager du en massedatabaseimport eller -eksport? Brug CSV — enhver database understøtter det nativt.
  • Har data blandede typer (booleaner, tal, nuller)? Brug JSON for at undgå typeinferens-fejl på modtagersiden.
  • Vil filen blive behandlet række for række i en streaming-pipeline? Overvej NDJSON som et mellemgrund.
  • Gemmer du konfiguration? Brug JSON (eller YAML hvis kommentarer er vigtige for dig).
  • Behøver skemaet at variere per post? JSON. CSV håndhæver de samme kolonner på hver række.
Det ærlige standardvalg: Hvis du bygger noget til andre udviklere eller maskiner at forbruge, brug JSON. Hvis du giver data til et menneske der åbner det i et regneark, brug CSV. Hvis du bygger en datapipeline der behandler millioner af strukturerede poster, overvej NDJSON.

Opsummering

CSV og JSON konkurrerer ikke rigtig — de løser forskellige problemer. CSV er det rigtige værktøj når dine data er en tabel og du vil have maksimal kompatibilitet med regneark- og databaseværktøjer. JSON er det rigtige værktøj når dine data har struktur, typer eller indlejring, og når du taler med API'er eller applikationer.

Beslutningen er normalt ikke svær når du kigger på den faktiske form af data. Flade rækker af sensoraflæsninger? CSV. Et API-svar med indlejrede brugerprofiler og indlejrede ordrehistorikker? JSON. En streaminglog af strukturerede hændelser? NDJSON. Tilpas formatet til formen af data og værktøjerne i begge ender, og du vil sjældent gå galt.