一文讀懂大數據時代的數據格式特征:CSV、JSON、Parquet、Avro、ORC

本文將詳細介紹五種重要的數據格式:
?CSV
?JSON
?Parquet
?Avro
?ORC
在大數據時代,數據源之間的數據遷移和存儲需要更具策略性的方法。如果沒有優化的決策,通過 ETL 流程處理 TB 級數據可能會耗費大量時間和成本。本地部署系統雖然相對容易發現問題,但其基礎設施不會自動適應新的情況,問題必須手動解決。
然而,在云端,資源可以自動擴展。雖然我們可能認為一切運行順暢,但一些被忽略的小步驟卻可能導致數萬元的不必要成本。在我看來,根據項目需求選擇合適的數據格式是大數據時代最關鍵的決策之一。
存儲在 S3 中的物聯網數據應該采用 CSV 格式還是 Parquet 格式?每周銷售報告文件的最佳格式是什么?大小文件是否應該使用相同的格式?只有充分了解每種數據格式的特性,才能有效地做出這些決策。
近年來,某些格式——尤其是 Parquet 和 Avro——越來越受歡迎。盡管它們存在一些缺點,但它們的靈活性,尤其是在云環境中,極大地促進了它們的應用。在本文中,我將解釋這些格式的特性、優勢和劣勢,并討論哪種格式最適合特定場景。
一、CSV
CSV是一種基于文本的表格數據格式,其中每一行代表一條記錄。記錄中的列或字段通常用分隔符(最常見的是逗號)分隔。第一行通常包含列名作為標題。CSV 格式被廣泛支持,因此成為數據交換的熱門選擇。
1.編碼
CSV 文件通常采用UTF-8編碼,這樣可以確保字符兼容性并使文件可壓縮。
2.優勢
?易于閱讀: CSV 文件易于閱讀和理解。
?通用性強: 幾乎所有編程語言和工具都支持它。
?易于使用:可以手動生成、編輯和檢查。
?兼容性:與電子表格和臨時分析工具兼容。
3.缺點
?我認為,這種格式最大的缺點之一是它不存儲元數據,不強制執行模式或數據類型,并且默認情況下將所有數據都視為文本。(例如,當使用其他工具讀取 CSV 文件時,包含年齡等數值的列可能會被解釋為整數,但這完全是一種解釋,可能不正確,需要手動驗證。否則,錯誤在所難免。)
?由于其體積龐大且 I/O 速度慢,因此對于大型數據集來說效率低下。與 Parquet 格式相比,根據具體情況,它可能占用大約 10 倍的空間。
?CSV格式不適用于嵌套數據,這是由于CSV格式本身的設計缺陷造成的。例如,在更適合嵌套數據的格式(例如JSON)中,嵌套結構如下所示:
{
"user" : { "id" : 123 , "name" : "Alice" } ,
"actions" : [ { "type" : "click" , "time" : "2025-11-05T12:00Z" } ]
}相同的 CSV 數據必須以 JSON 字符串的形式表示在單個單元格中:
user_id,user_name,actions
123,Alice,"[{""type"":""click"",""time"":""2025-11-05T12:00Z""}]""[{" "type" ":" "click" "," "time" ":" "2025-11-05T12:00Z" "}]"這使得閱讀、篩選和分析變得更加困難。
4.何時選擇 CSV 格式
?適用于對人類可讀性要求較高的中小型數據集。
?應用程序、分析師或團隊之間輕松共享數據。
?不支持二進制或列式格式的系統或工具。
?快速原型制作或從電子表格(Excel、Google Sheets)導出。
二、JSON
多年來,JSON 一直是最流行的數據格式之一。它可以被視為一種通用語言,使不同的應用程序能夠相互理解。其主要目的是促進 Web 服務和應用程序之間的數據交換。在 JSON 出現之前,XML 曾被廣泛用于此目的,但它存在諸多缺陷。
XML格式非常冗長,難以閱讀,尤其是在處理冗長且嵌套結構的情況下。它占用大量存儲空間,解析XML文件會消耗大量的CPU和內存資源,因此不適合處理大數據。此外,XML的兼容性也有限,通常需要專門的庫才能解析。
一個簡單的 XML 結構示例:
<user>
<id> 1 </id>
<name> Alice </name>
<is_active> true </is_active>
<address>
<city> Berlin </city>
<postal_code> 10115 </postal_code>
</address>
<hobbies>
<hobby> music </hobby>
<hobby> cycling </hobby>
</hobbies>
</user>JSON 隨后應運而生,它是一種更簡潔、更緊湊、人機可讀且通用兼容的格式,極大地簡化了跨語言數據交換。JSON以文本格式存儲鍵值對數據。它支持嵌套和層級結構,能夠自然地表示復雜且深度嵌套的數據。其通用性使其被廣泛用于 API 數據傳輸和配置文件。
一個簡單的JSON結構示例:
{ "id" : 1 ,
"name" : "Alice" ,
"is_active" : true ,
"address" : { "city" : "Berlin" , "postal_code" : "10115"
} ,
"hobbies" : [ "music" , "cycling" ]
}1.編碼
UTF-8 通常被使用,因為它既兼容 ASCII,又支持國際字符。由于采用了 UTF-8 編碼,JSON 文件可以在不同的平臺上無縫共享。
2.優勢
?人類可讀: JSON 文件是基于文本的,易于人類閱讀。
?支持嵌套數據:可以自然地表示復雜和分層的數據結構。
?通用互操作性:幾乎所有現代編程語言都支持。
?無模式靈活性:每條記錄可以有不同的字段;不需要嚴格的模式。
?API友好: REST和GraphQL服務的標準格式。
3.缺點
?存儲效率低下:每個記錄中都重復出現鍵,這會增加大型數據集的大小。雖然它適用于消息傳遞,但并不適合大規模存儲。
?不強制類型:數字、布爾值或空值均被視為文本;正確的類型由應用程序自行決定。這種缺乏強制的做法可能是一個缺點,尤其是在 ETL 流程中,新數據可能需要持續關注以避免類型錯誤。
?解析成本:與二進制格式相比,CPU 和 RAM 使用率更高,尤其是對于大文件而言。
?無元數據: JSON 中不包含最小值、最大值或空計數等信息。
?大文件處理:大文件需要流式傳輸或分塊傳輸;一次性將整個文件加載到內存中是不切實際的。
4.何時選擇 JSON
?API 數據交換(REST/GraphQL): JSON 非常適合在不同系統和編程語言之間傳輸數據。它為 Web 服務、微服務和移動應用程序提供了一種標準、快速且易于解析的格式。
?適用于快速原型設計和共享的中小型數據集:雖然 JSON 不是存儲大型數據的最佳選擇,但對于中小型數據集來說效果很好。
?人的可讀性很重要:與 XML 或二進制格式相比,其基于文本的鍵值結構使得錯誤和缺失字段更容易識別和調試。
?嵌套和分層數據: JSON 自然地支持嵌套對象和數組,可以輕松地以清晰有序的方式表示復雜的結構,例如包含地址和訂單的用戶對象。
三、Parquet
Parquet 是當今最流行的數據格式之一,專為Apache Hadoop 生態系統中的大數據分析而設計。它的主要目標是在高效存儲大型數據集的同時,優化查詢和分析性能。其最重要的特性是列式結構,這顯著提升了查詢和存儲性能。從很多方面來看,Parquet 都可以被視為大數據時代的主流。
Parquet文件的結構
Parquet文件由三個主要層組成:
Parquet 文件

?行組: Parquet 文件的一部分(例如,100 萬行一組)。
?列塊:行組中特定列的數據(e.g., user_id, age, country)。
??注意:每一列(例如,country)并沒有存儲在整個文件的單個連續塊中,而是作為每個行組中的單獨列塊存儲。
行組允許并行讀取和基于行的過濾(謂詞下推),從而只讀取必要的行塊,降低 I/O 成本并提高讀取性能。
1.編碼
Parquet 格式以二進制列式結構存儲數據。雖然 Parquet 中的文本數據可能使用 UTF-8 編碼,但其效率并非源于編碼本身,而是源于其他特性,我們將在下文討論這些特性。
2.優勢
(1)列式結構
采用列式結構可以顯著提高 Parquet 格式的效率。其最大的優勢在于,在大型查詢中,系統只會讀取所需的列,而忽略不必要的列。這不僅提高了I/O 性能,還降低了成本。
對基于行的格式(例如 CSV)和基于列的格式(例如 Parquet)的數據進行查詢的方式如下:

(2)基于行的查詢(CSV)
在 CSV 文件中,所有行都以文本形式存儲:
1,愛麗絲,30,美國,100
2,鮑勃,25,美國,200
3,卡羅爾,40,德國,150
4,戴夫,35,德國,300
5,伊芙,28,美國,250查詢: “美國客戶總消費額”→ 僅需要列country和spend
因為 CSV 是基于行的,所以會讀取和解析所有行,包括id、name、age。
I/O 成本: 5 行 × 5 列(讀取整個文件)。
(3)列式查詢(Parquet)
在 Parquet 格式中,列存儲在單獨的塊中:
列ID:1、2、3、4、5 ;
列名稱:Alice、Bob、Carol 、Dave 、Eve;
列年齡:30、25、40、35、28 ;
列國家/地區: US 、US、DE 、DE、US ;
列消費金額:100、200、150、300、250
?查詢: “美國客戶總支出”→ 僅讀取country和spend列塊。
?id、name 和 age 不會從磁盤讀取,從而降低了 I/O 和 CPU 開銷。
?列式格式結合字典編碼、游程編碼(RLE)和位打包(bit-packing)可減小文件體積并加速讀取。
格式 | 讀取的數據 |I/O-----|-------------|------CSV(行式)|所有行 + 所有列|高Parquet(列式)|僅 country 和 spend 的數據塊|低
(4)行組
行分組不僅按列劃分數據,還按行劃分數據,具體如下:
?提高I/O 性能
?減少過多的隨機磁盤訪問
例如:一個文件有 3 個行組,每個行組有 50 萬行:

如果我們只查詢 ` idA` 和 ` ageB`,就不會訪問 `C` name、country`D` 和 `D`salary中的 450 萬行數據,從而節省大量資源。行組也可以并行讀取,進一步提升性能。
如果我們需要的數據只在一個行組中,則跳過其他行組,從而節省高達 80-90% 的 I/O。
(5)字典編碼
Parquet 的另一個效率提升之處在于字典編碼。重復值存儲在字典中,并通過索引進行引用,從而減少了高度重復數據的存儲空間。
例子:
列:[美國, 美國, 德國,美國,德國, … ]
字典:{ 0 :美國, 1:德國}
編碼列: [ 0 , 0 , 1 , 0 , 1 , … ] 如果我們有 10K 行:6K United States+ 4K Germany,我們存儲索引而不是完整的字符串,最多可以節省約 90% 的空間。
原始文本(CSV):
6,000 × 13 = 78,000字節4,000 × 7 = 28,000字節總計:106,000字節≈ 103.5 KB字典編碼(Parquet ) 10,000行→ 2個類別→每行1字節(或至少1位)總編碼:10,000字節≈ 9.8 KB
(6)游程編碼(RLE)
RLE 對連續重復的值進行數值計數:
列: [ 0 , 0 , 0 , 1 , 1 , 2 , 2 , 2 , 2 ]
RLE: [ (0 , 3 ) , (1 , 2 ) , (2 , 4 ) ] # 前三個值為 0 等。
位打包
?數值使用最少位數。
例如:值為 0-3 的列只需要2 位而不是 32 位。
(7)模式強制執行與元數據
Parquet 文件包含有關文件及其數據類型的元數據。
元數據存儲模式和數據類型,以便下游消費者可以信任數據類型,而無需重新定義模式或依賴自動檢測(自動檢測容易出錯)。
元數據還包括 Parquet 版本、創建者、寫入工具(Spark、Pandas 等)、列最小值/最大值(啟用謂詞下推)、空值計數和值計數。
3.缺點
Parquet 格式不具備可讀性:它是一種二進制格式;直接讀取它只會顯示原始二進制數據。需要使用專門的工具(例如 PyArrow、Pandas、Spark、DuckDB)來檢查或處理數據。
小型數據集的寫入開銷:元數據、編碼信息和字典表會使 Parquet 文件比小型 CSV 文件大得多。例如,一個包含幾百行的 CSV 文件可能只有 10 KB,而相同數據的 Parquet 文件則可能需要 100 KB。
兼容性問題:并非所有系統或輕量級工具都直接支持 Parquet 格式,包括:
?遺留系統
?基本電子表格或商業智能工具
?小型嵌入式或基于腳本的解決方案
?通常需要中間庫(例如 Pandas、PyArrow、Spark)才能讀取。
4.何時選擇Parquet
?大規模分析和大數據查詢: Parquet 格式非常適合擁有數百萬甚至數十億行數據的數據集,尤其適用于對查詢性能和 I/O 效率要求極高的情況。其列式結構允許僅讀取必要的列,從而減少磁盤和內存使用量。
?嵌套或復雜的數據結構: Parquet 支持結構體、數組和映射等復雜數據類型,使其適用于分層或半結構化數據,而這些數據在 CSV 等基于行的格式中會顯得很繁瑣。
?云存儲和成本效益:在云環境中,僅讀取所需列可降低 I/O 和計算成本。Parquet 的壓縮和編碼特性可進一步減少存儲占用。
?ETL管道和分析框架: Parquet可與Spark、Hive、Presto和DuckDB等大數據工具無縫集成。當數據將被多個下游分析系統使用時,它堪稱完美之選。
?基于列值過濾場景:當查詢涉及基于列值進行過濾時(例如,WHERE country = 'US'),Parquet 的行組和元數據允許跳過不相關的數據塊,從而大幅提高查詢速度。
四、Avro
Apache Avro 是 Apache Hadoop 生態系統中最古老、最成熟的數據格式之一。它由 Hadoop 的創建者 Doug Cutting 開發。其主要目的是解決數據可移植性和模式定義方面的不足。Avro基于行,與早期格式不同的是,它采用二進制而非文本格式。這使其更高效、更快速、更節省空間。
例如,考慮一個 10 位數:
1234567890
?在 CSV 或 JSON 格式中,每個數字都存儲為一個字符(每個數字占用 1 個字節):
'1' → 00110001
'2' → 00110010
...
'0' → 00110000
?總計:10 字節。解析需要將每個字符轉換回整數。
?在像 Avro 這樣的二進制格式中,該數字以 int32(4 字節)形式存儲,節省了約 6 個字節,并且允許直接內存訪問而無需解析,從而顯著提升了速度。
Avro 也像 Parquet 一樣提供模式強制執行,這意味著模式存儲在文件元數據中。
1.文件結構
Avro 文件由三個主要部分組成:
Avro 文件

?頭部:包含描述數據結構的“魔數”和模式定義(JSON 格式)。
?數據塊:以壓縮二進制形式存儲實際數據。數據塊支持并行處理;程序可以跳過不需要的數據塊以加快訪問速度。
?同步標記:充當斷點,幫助在文件損壞時恢復數據。
編碼
?Avro 以二進制格式存儲數據,比 JSON 或 CSV 格式小得多。
?無需進行文本解析,因此CPU 使用率低。
2.優勢
?模式演化與類型強制執行
?該模式嵌入在文件中,確保類型安全和向前/向后兼容性。
向后兼容性示例:
舊模式:
{
"type" : "record" ,
"name" : "User" ,
"fields" : [ { "name" : "id" , "type" : "int" } ,
{ "name" : "name" , "type" : "string" }
]
}舊數據(二進制表示,以 JSON 格式顯示):
{ "id" : 1 , "name" : "Alice" }
{ "id" : 2 , "name" : "Bob" }新增模式,添加了字段(is_active)及其默認值true:
{
"type" : "record" ,
"name" : "User" ,
"fields" : [
{ "name" : "id" , "type" : "int" } ,
{ "name" : "name" , "type" : "string" } ,
{ "name" : "is_active" , "type" : "boolean" , "default" : true }
]
}使用新模式讀取舊文件會產生以下結果:
{ "id" : 1 , "name" : "Alice" , "is_active" : true }
{ "id" : 2 , "name" : "Bob" , "is_active" : true }?舊數據不包含新字段,但Avro 會使用默認值填充該字段,從而確保向后兼容性。向前兼容性則以相反的方向實現。
緊湊二進制格式
?比文本格式小得多(大約是 JSON 大小的 10-20%),但比 Parquet 大。
快速序列化和反序列化
?序列化和反序列化數據時 CPU 使用率極低,使其成為Kafka、Flink 和 Spark Streaming 等實時系統的理想選擇。
與語言無關
?模式在 JSON 中定義,數據是二進制的 → 可以輕松地在 Python、Java、Go、C++、Scala 等中使用。
非常適合流媒體播放
?基于行的結構意味著每個記錄都是獨立的,非常適合基于事件的處理(Kafka 主題、消息傳遞系統)。
3.缺點
人類無法閱讀
二進制格式無法直接讀取;需要 PyArrow、Avro 工具或 Spark 等工具進行檢查。
基于行的結構
SELECT AVG(price)對于分析查詢(例如,在大數據集上),列式格式(Parquet/ORC)效率較低。
讀取模式所需
沒有模式就無法讀取數據。模式必須嵌入在文件中或可從外部獲取。
壓縮技術不如Parquet/ORC先進
行式存儲限制了壓縮效率;列式格式可以實現更好的存儲空間縮減。
4.何時選擇 Avro
流式傳輸和消息傳遞系統: Kafka、Flink、Pulsar 等,其中事件需要快速序列化。
模式管理和向后兼容性:跨版本自動模式演化。
類型安全:與 JSON 不同,Avro 強制執行數據類型。
適度的存儲優化:比文本格式小,但不需要列式壓縮。
高頻 ETL 和微服務:適用于服務間數據流密集的系統。
五、ORC(優化行列式)
ORC 是一種專為 Hadoop 生態系統開發的高性能列式二進制數據格式。它專為分析海量數據而設計,因此具有很高的查詢效率和壓縮率。它也像 Parquet 一樣具有模式強制執行功能。
1.文件結構
ORC 文件包含三個主要部分:

Postscript:數據以大塊形式存儲,每列都是獨立的。也就是說,一個條帶包含一組行的逐列數據。
Footer:包含所有架構、統計信息和條帶位置。
Stripes:提供有關壓縮、文件格式版本和頁腳長度的信息。
下面我們通過一個例子來更清楚地理解這三個部分;
假設我們有一個客戶表;

ORC 文件

2.編碼方法
ORC 的編碼方式與 Parquet 非常相似;我們在此不再贅述。您可以在上面的 Parquet 部分閱讀相關內容。不過,我們可以大致討論三種基本方法;
字典編碼:對于重復值,創建一個字典,并存儲字典中的索引而不是數據本身。
游程編碼(RLE):連續相同的值用一個值及其重復次數表示。
位打包:對于數值,使用最少的位數,例如,對于 0 到 3 之間的值,只需 2 位就足夠了。
3.優勢
?高壓縮比: ORC 具有很高的壓縮比。這主要是因為數據是按列存儲的,并且相似的數據是連續存儲的。我們在 Parquet 部分已經提到過這一點,并指出這種方法稱為游程編碼 (Run-Length Encoding)。
?模式強制執行:與 Parquet 格式一樣,ORC 也具有模式強制執行機制。我們前面已經討論過它的重要性。
?快速分析: ORC 與 Parquet 類似,僅在需要時才訪問數據,從而顯著提升讀取性能。更多詳細信息,請參閱 Parquet 部分。
4.缺點
ORC的缺點與Parquet的缺點非常相似;簡而言之,這些缺點包括:
?不可讀:由于 ORC 是二進制格式,因此無法瀏覽或讀取。
?基于行的更新很困難:它專為追加或批量分析而設計,而非事務性的行級更新。它更側重于分析,因此不適合行級更新。這是因為數據以列為單位存儲在較大的數據塊(條帶或行組)中;更改單行需要重寫所有相關的列數據塊。
?小數據集的元數據開銷:對于非常小的表,元數據和條帶開銷可能會使 ORC 比 CSV 或 Avro 更大。
?工具依賴性:某些輕量級工具或舊系統可能不支持 ORC 原生支持。
5.何時選擇 ORC
?對大型數據集進行分析查詢: ORC 在讀取密集型分析工作負載(如 Hive 或 Spark 中的聚合、過濾和連接)中表現出色。
?需要高壓縮率:重復性或低基數數據集可受益于 ORC 的列式壓縮。
?Hadoop 生態系統集成:與 Hive、Spark、Presto、Impala 或 HDFS/S3 存儲配合使用時非常理想。
?謂詞下推/更快的過濾: ORC 的條帶級元數據可以高效地跳過不必要的數據。
?具有批量追加功能的穩定模式:非常適合追加密集型管道,但不太適合事務性行更新。
6.Parquet 與 ORC區別
這兩種文件類型都是二進制、列式存儲,并且在許多方面都使用非常相似的方法。然而,它們在某些方面也存在差異。首先,ORC 格式的優化更為激進。因此,在某些情況下,ORC 格式可以獲得更好的壓縮效果,并且由于其元數據更詳細、更全面,因此也能提供更好的讀取性能。
我們將在平臺上使用的工具也很重要。ORC 主要面向 Hive 和 Hadoop,因此在這里速度可能更快;而 Parquet 在云端和異構系統中表現更佳,具有更強的平臺兼容性和通用性。雖然這兩種工具通常都適用于批量分析,但使用 ORC 添加少量數據或進行基于行的數據更改效率較低。Parquet 在這方面則更加靈活,可以根據具體情況用于此類操作。讓我們簡要比較一下這兩種工具:

今天,我們介紹了大數據生態系統中的關鍵數據格式:CSV、JSON、Parquet、Avro 和 ORC。我們分析了它們的主要特性、優勢、劣勢以及各自最適用的場景,包括存儲、性能、模式強制執行、壓縮和兼容性等方面的考量。您可以在下方找到總結表。
































