首頁 >科技週邊 >IT業界 >數據序列化比較:JSON,YAML,BSON,MessagePack

數據序列化比較:JSON,YAML,BSON,MessagePack

William Shakespeare
William Shakespeare原創
2025-02-18 12:57:09917瀏覽

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

網絡數據交換的實際標準是 JSON (JavaScript 對象表示法),但它也存在缺點,在某些情況下,其他格式可能更適用。本文將比較各種替代方案的優缺點,包括易用性和性能。

注意:本文不會詳細介紹實現細節,但如果您是 Ruby 程序員,請查看 Dhaivat 編寫的這篇文章,文章介紹了在 Ruby 中實現一些序列化格式的方法。

關鍵要點

  • JSON (JavaScript 對象表示法) 是最廣泛使用的用於數據序列化的格式,它提供人類可讀的代碼、簡單的規範和廣泛的支持。但是,它也有一些局限性,尤其是在編碼二進制數據時。
  • BSON (二進制 JSON) 是 JSON 類文檔的二進制編碼序列化。它提供方便的二進制信息存儲,旨在進行快速的內存操作,並且是 MongoDB 的主要數據表示形式。但是,在序列化時,它可能比 JSON 更昂貴。
  • MessagePack 是一種用於序列化的二進制格式,旨在實現高效的網絡傳輸。在速度和大小方面,它通常優於 BSON,並且提供更好的 JSON 兼容性。
  • YAML (YAML 不是標記語言) 是一種用於序列化的純文本格式,它提供人類可讀的代碼和緊湊的代碼。它特別適用於查看和編輯數據結構。但是,它的規範比 JSON 的規範大得多,因此更複雜。

什麼是數據序列化

根據維基百科的定義,序列化是:

將數據結構或對象狀態轉換為可以存儲(例如,存儲在文件或內存緩衝區中,或通過網絡連接鏈路傳輸)並在以後在相同或其他計算機環境中重建的格式的過程。

假設您想收集關於一群人的某些數據——姓名、姓氏、暱稱、出生日期、他們演奏的樂器。您可以輕鬆地設置一個電子表格,定義一些列,並將每一行作為一個條目。您可以更進一步,定義出生日期列必須是一個數字,並且樂器列可以是一個選項列表。它看起來像這樣:

姓名 姓氏 出生日期 暱稱 樂器 William Bailey 1962 Axl Rose vocals, piano Saul Hudson 1965 Slash guitar

或多或少,您在那裡所做的是定義一個數據結構;如果您只需要電子表格格式,那麼您會做得很好。問題是,如果您想與數據庫或網站交換此信息,那麼即使底層語義總體上相同,這些數據結構在這些其他平台上的實現機制也會大相徑庭。您不能只將電子表格插入 Web 應用程序,除非該應用程序已為此專門設計。除非您有某種導出工具或網關,否則您無法將信息從網站傳輸到數據庫。

讓我們假設我們的網站已經在其內部邏輯中實現了這些數據結構,並且它根本無法處理電子表格格式。為了解決這些問題,您可以將這些數據結構轉換為一種易於在不同應用程序、架構或其他內容之間共享的格式:您將它們序列化。通過這樣做,您可以確保不僅可以跨平台傳輸這些數據,而且可以在稱為反序列化的反向過程中重建它們。此外,如果從網站交換回電子表格,您將獲得原始對象的語義上相同的克隆——也就是說,看起來與您最初發送的行完全相同的行。

簡而言之:序列化數據是找到某種易於在不同應用程序之間共享的通用格式。

格式

JSON

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

JSON (JavaScript 對象表示法) 是一種輕量級的數據交換格式。它易於人類閱讀和編寫;它易於機器解析和生成。

JSON 是最廣泛使用的數據序列化格式,它具有以下特性:

  • (大部分)人類可讀的代碼:即使代碼已被模糊處理或縮小,您也可以始終使用 JSONLint 等工具對其進行縮進並使其再次可讀。
  • 非常簡單直接的規範:整個規範的摘要可以放在一頁紙上(如 JSON 網站上顯示的那樣)。
  • 廣泛的支持:不僅每種編程語言或 IDE 都帶有 JSON 支持,而且許多 Web 服務 API 也提供 JSON 作為數據交換的一種方式。
  • 作為 JavaScript 的子集,它支持以下 JavaScript 數據類型:
    • 字符串
    • 數字
    • 對象
    • 數組
    • true 和 false
    • null

以下是我們的先前電子表格在 JSON 中序列化後的樣子:

<code>[
  {
    "name": "William",
    "last name": "Bailey",
    "dob": 1962,
    "nickname": "Axl Rose",
    "instruments": [
      "vocals",
      "piano"
    ]
  },
  {
    "name": "Saul",
    "last name": "Hudson",
    "dob": 1965,
    "nickname": "Slash",
    "instruments": [
      "guitar"
    ]
  }
]
</code>

BSON

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

BSON,即二進制 JSON,是 JSON 類文檔的二進制編碼序列化……它還包含允許表示不屬於 JSON 規範的數據類型的擴展。

JSON 是一種純文本格式,雖然二進制數據可以編碼為文本,但這有一定的局限性,並且會使 JSON 文件非常大。 BSON 用於處理這些問題。

它具有以下特性:

  • 方便的二進制信息存儲:更適合交換圖像和附件
  • 旨在進行快速的內存操作
  • 簡單規範:與 JSON 一樣,BSON 也有一個非常簡短和簡單的規範
  • MongoDB 的主要數據表示形式:BSON 旨在易於遍歷
  • 額外的數據類型:
    • 雙精度(64 位 IEEE 754 浮點數)
    • 日期(自 Unix 紀元以來的毫秒數)
    • 字節數組(二進制數據)
    • BSON 對象和 BSON 數組
    • JavaScript 代碼
    • MD5 二進制數據
    • 正則表達式

MessagePack

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

它類似於 JSON。但速度更快,體積更小。

MessagePack(也稱為 msgpack)是另一種用於序列化的二進制格式。不像 BSON 那麼出名,但值得一看。

其特性包括:

  • 旨在實現高效的網絡傳輸
  • 比 BSON 更好的 JSON 兼容性:正如 Sadayuki Furuhashi 在這篇 Stack Overflow 帖子中解釋的那樣
  • 比 BSON 更小:它的開銷比 BSON 更小,並且大多數情況下可以序列化更小的對象
  • 類型檢查:它支持靜態類型
  • 流式 API:支持流式反序列化器,這對於網絡通信非常有用。

YAML

YAML:YAML 不是標記語言。它是什麼:YAML 是一種適用於所有編程語言的人性化數據序列化標準。

回到純文本格式,YAML 是 JSON 的一種替代方案:

  • (真正)人類可讀的代碼:YAML 的可讀性如此之高,以至於即使其首頁內容也以 YAML 顯示以說明這一點
  • 緊湊的代碼:使用空格縮進表示結構,無需引號或括號
  • 關係數據的語法:允許使用錨點(&)和別名(*)進行內部引用
  • 特別適用於查看/編輯數據結構:例如配置文件、調試期間的轉儲和文檔標題
  • 一組豐富的與語言無關的類型:
    • 集合:
      • 無序鍵集(!!map)
      • 有序鍵序列(!!omap)
      • 有序鍵序列(!!pairs)
      • 不相等值的無序集(!!set)
      • 任意值的序列(!!seq)
    • 標量類型:
      • 空值(~,null)
      • 十進制 (1234)、十六進制 (0x4D2) 和八進制 (02333) 整數
      • 固定 (1_230.15) 和指數 (12.3015e 02) 浮點數
      • 無窮大 (.inf, -.Inf) 和非數字 (.NAN)
      • true (Y, true, Yes, ON) 和 false (n, FALSE, No, off)
      • 使用 base64 編碼的二進制 (!!binary)
      • 時間戳 (!!timestamp)。

以下是我們的電子表格在 YAML 中序列化後的樣子:

<code>[
  {
    "name": "William",
    "last name": "Bailey",
    "dob": 1962,
    "nickname": "Axl Rose",
    "instruments": [
      "vocals",
      "piano"
    ]
  },
  {
    "name": "Saul",
    "last name": "Hudson",
    "dob": 1965,
    "nickname": "Slash",
    "instruments": [
      "guitar"
    ]
  }
]
</code>

其他格式

還有許多其他序列化格式,例如 Protocol Buffers (protobuf,也是二進制格式),我已經(以相當隨意的方式)省略了。如果您只想了解所有可能的格式,請查看維基百科關於數據序列化格式比較的內容。

……HDF5?

Data Serialization Comparison: JSON, YAML, BSON, MessagePack

我們在這裡會稍微偏離主題一點。分層數據格式版本 5 (HDF5) 並不是真正用於序列化,而是用於存儲,並且它正在席捲數據科學和其他行業。它是一種非常快速且通用的格式,不僅可以用於存儲許多數據結構,還可以用作關係數據庫的替代品。

為了結束這段插曲,讓我們只提一下,如果您正在使用 BSON 和 MessagePack 等二進制格式來存儲/交換大量信息,您可能非常想看看 HDF5。

基準測試和比較

出現的一種模式是,BSON 在序列化時可能比 JSON 更昂貴,但在反序列化時更快;並且 MessagePack 在任何操作上都比兩者都快。此外,由於其開銷,儘管是二進制格式,但在存儲非二進制數據時,BSON 文件有時可能比 JSON 文件更大。一些可以參考的鏈接:

  • Maxim Novak 在 M@X on DEV 上進行的序列化性能比較(C#/.NET)。
  • Ilya Grigorik 在 ivita.com 上發表的 Protocol Buffers、Avro、Thrift 和 MessagePack。
  • Karlin Fox 在 Atomic Object 上撰寫的二進制序列化之旅指南。
  • Matthew Rocklin 撰寫的有效存儲 Pandas DataFrame。
  • Wesley Tanaka 撰寫的 MessagePack 與 JSON 與 BSON 的比較。

還值得注意的是,即使對於相同的格式,性能也可能取決於您選擇的序列化器和解析器。

備註和評論

雖然聽起來很傻,但 BSON 具有名稱的優勢:人們會自動將 MongoDB 開發的格式 (BSON) 與標準 (JSON) 關聯起來,它們之間並沒有關聯。因此,在搜索 JSON 的二進制替代方案時,您也可以考慮其他選項。

事實上,MessagePack 似乎在各個方面都優於 BSON:它更快、更小,而且它甚至比 BSON 更兼容 JSON。 (事實上,如果您已經在使用 JSON,MessagePack 幾乎是一個即插即用的優化。)也許作為一名“記者”,我應該更平衡一些,但作為一名開發人員,這毫無疑問。

儘管如此,BSON 是 MongoDB 用於存儲和表示數據的格式,因此如果您正在使用這個 NoSQL 數據庫,那麼堅持使用它是有原因的。

當然,序列化不僅僅是關於存儲二進制數據。誠然,JSON 的目標不同——即“人類可讀”。但是,稍微注意一下就會發現 YAML 在這方面做得更好。

但是,YAML 規範非常龐大,特別是與 JSON 的規範相比。但可以說,它必須如此,因為它包含更多的數據類型和特性。

另一方面,不能忽視的是,JSON 的簡單性在其被採用作為其他序列化格式的關鍵作用。它依賴於一種已經存在的廣泛使用的語言 JavaScript,如果您了解或接觸過 JS(如果您在 Web 開發行業,您就會了解),那麼您就已經了解 JSON 了。

那麼為什麼現在不採用 YAML 呢?在許多情況下,這並不容易。 JSON 仍然在Web API 中佔有一席之地,因為您可以輕鬆地將JSON 代碼嵌入HTTP 請求中(對於GET,如在URL 中,以及POST,如在發送表單中):該格式會讓您知道傳輸是否突然中斷,因為代碼將自動呈現無效,而YAML 和其他競爭性純文本格式可能並非如此。此外,您仍然需要在某個時刻與基於 JSON 的 API 和遺留代碼進行交互,並且維護相同目的(數據序列化)的兩個代碼片段(JSON 和 YAML 方法)始終是一件痛苦的事情。

但話又說回來,這些部分上與推動我們倒退並阻止我們採用更新、更高效的技術(例如:Python 3 而不是 Python 2)的論點相同。我曾經想過一分鐘,我們程序員和企業家是創新者,不是嗎?

關於數據序列化和 JSON 替代方案的常見問題

JSON 和 YAML 之間的主要區別是什麼?

JSON 和 YAML 都是數據序列化格式,但它們有一些關鍵區別。 JSON 是 JavaScript 的一個子集,由於其與 JavaScript 的兼容性,因此經常在 Web 應用程序中使用。它使用簡單的語法,易於閱讀和編寫。但是,它缺少一些功能,例如註釋和多行字符串。另一方面,YAML 是 JSON 的超集,並且具有更人性化的語法。它支持註釋和多行字符串,使其更易於用作配置文件。但是,它比 JSON 更複雜,並且支持度不如 JSON 廣泛。

BSON 與 JSON 和 YAML 相比如何?

BSON 或二進制 JSON 是 JSON 類文檔的二進製表示。它旨在在空間上高效,而且在計算密集型場景(如網絡傳輸)中也是如此。 BSON 可以存儲比 JSON 更多的數據類型,包括二進制和日期數據類型。但是,它不如 JSON 或 YAML 人類可讀,並且主要用於 MongoDB 中存儲和檢索數據。

什麼是 MessagePack,它與其他數據序列化格式相比如何?

MessagePack 是一種類似於 JSON 但更高效的二進制序列化格式。它緊湊、快速,並支持各種數據類型。它經常用於對性能要求很高的應用程序中,例如實時流式應用程序。但是,與 BSON 一樣,它不如 JSON 或 YAML 人類可讀。

JSON 的其他替代方案有哪些?

是的,JSON 有幾種其他替代方案,包括 XML、Protobuf 和 Avro。 XML 是一種人類可讀的標記語言,支持複雜的數據結構,但它比 JSON 更冗長。 Protobuf 或 Protocol Buffers 是一種由 Google 開發的二進制序列化格式,它緊湊且快速,但不可讀。 Avro 是一種由 Apache 開發的二進制序列化格式,支持模式演變,使其適合長期數據存儲。

我應該使用哪種數據序列化格式?

數據序列化格式的選擇取決於您的具體需求。如果您需要一種人類可讀且易於使用的格式,那麼 JSON 或 YAML 可能是最佳選擇。如果您需要一種緊湊且快速的格式,那麼 MessagePack 或 BSON 可能更合適。如果您需要一種支持模式演變的格式,那麼 Avro 可能是最佳選擇。在做出決定之前,了解每種格式的優缺點非常重要。

我可以在同一個應用程序中使用多種數據序列化格式嗎?

是的,可以在同一個應用程序中使用多種數據序列化格式。例如,您可以使用 JSON 在客戶端和服務器之間進行數據交換,並使用 BSON 在 MongoDB 中存儲數據。但是,使用多種格式可能會增加應用程序的複雜性,因此務必仔細權衡利弊。

如何在不同的序列化格式之間轉換數據?

有幾個庫和工具可以用於在不同的序列化格式之間轉換數據。例如,您可以使用 Python 中的 json 模塊在 JSON 和 Python 對象之間轉換數據,或者使用 yaml 模塊在 YAML 和 Python 對象之間轉換數據。還有一些在線工具,例如 json2yaml,可以用於在 JSON 和 YAML 之間轉換數據。

使用不同的數據序列化格式會帶來哪些性能影響?

使用不同的數據序列化格式的性能影響可能因具體用例而異。像 BSON 和 MessagePack 這樣的二進制格式通常比 JSON 和 YAML 等基於文本的格式更快、更緊湊。但是,它們不如人類可讀,這可能會使調試更加困難。還必須考慮用於序列化和反序列化數據的庫和工具的性能。

使用數據序列化格式時有哪些安全注意事項?

是的,使用數據序列化格式時,有一些安全注意事項。例如,如果 JSON 和 YAML 等某些格式未正確清理,則它們可以執行任意代碼,這可能會導致安全漏洞。務必使用受信任的庫和工具來序列化和反序列化數據,並清理任何用戶提供的數據。

如何了解更多關於數據序列化格式的信息?

在線有許多資源可以幫助您了解更多關於數據序列化格式的信息。您可以從閱讀每種格式的官方文檔開始,這些文檔通常包含教程和示例。在 Stack Overflow 和 Medium 等網站上還有許多教程和文章。最後,您可以在自己的項目中嘗試不同的格式以獲得實踐經驗。

以上是數據序列化比較:JSON,YAML,BSON,MessagePack的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn