网络数据交换的实际标准是 JSON (JavaScript 对象表示法),但它也存在缺点,在某些情况下,其他格式可能更适用。本文将比较各种替代方案的优缺点,包括易用性和性能。
注意:本文不会详细介绍实现细节,但如果您是 Ruby 程序员,请查看 Dhaivat 编写的这篇文章,文章介绍了在 Ruby 中实现一些序列化格式的方法。
根据维基百科的定义,序列化是:
将数据结构或对象状态转换为可以存储(例如,存储在文件或内存缓冲区中,或通过网络连接链路传输)并在以后在相同或其他计算机环境中重建的格式的过程。
假设您想收集关于一群人的某些数据——姓名、姓氏、昵称、出生日期、他们演奏的乐器。您可以轻松地设置一个电子表格,定义一些列,并将每一行作为一个条目。您可以更进一步,定义出生日期列必须是一个数字,并且乐器列可以是一个选项列表。它看起来像这样:
姓名
姓氏
出生日期
昵称
乐器
William Bailey 1962 Axl Rose vocals, piano Saul Hudson 1965 Slash guitar
或多或少,您在那里所做的是定义一个数据结构;如果您只需要电子表格格式,那么您会做得很好。问题是,如果您想与数据库或网站交换此信息,那么即使底层语义总体上相同,这些数据结构在这些其他平台上的实现机制也会大相径庭。您不能只将电子表格插入 Web 应用程序,除非该应用程序已为此专门设计。除非您有某种导出工具或网关,否则您无法将信息从网站传输到数据库。
让我们假设我们的网站已经在其内部逻辑中实现了这些数据结构,并且它根本无法处理电子表格格式。为了解决这些问题,您可以将这些数据结构转换为一种易于在不同应用程序、架构或其他内容之间共享的格式:您将它们序列化。通过这样做,您可以确保不仅可以跨平台传输这些数据,而且可以在称为反序列化的反向过程中重建它们。此外,如果从网站交换回电子表格,您将获得原始对象的语义上相同的克隆——也就是说,看起来与您最初发送的行完全相同的行。
简而言之:序列化数据是找到某种易于在不同应用程序之间共享的通用格式。
JSON (JavaScript 对象表示法) 是一种轻量级的数据交换格式。它易于人类阅读和编写;它易于机器解析和生成。
JSON 是最广泛使用的数据序列化格式,它具有以下特性:
以下是我们的先前电子表格在 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,即二进制 JSON,是 JSON 类文档的二进制编码序列化……它还包含允许表示不属于 JSON 规范的数据类型的扩展。
JSON 是一种纯文本格式,虽然二进制数据可以编码为文本,但这有一定的局限性,并且会使 JSON 文件非常大。BSON 用于处理这些问题。
它具有以下特性:
它类似于 JSON。但速度更快,体积更小。
MessagePack(也称为 msgpack)是另一种用于序列化的二进制格式。不像 BSON 那么出名,但值得一看。
其特性包括:
YAML:YAML 不是标记语言。它是什么:YAML 是一种适用于所有编程语言的人性化数据序列化标准。
回到纯文本格式,YAML 是 JSON 的一种替代方案:
以下是我们的电子表格在 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,也是二进制格式),我已经(以相当随意的方式)省略了。如果您只想了解所有可能的格式,请查看维基百科关于数据序列化格式比较的内容。
我们在这里会稍微偏离主题一点。分层数据格式版本 5 (HDF5) 并不是真正用于序列化,而是用于存储,并且它正在席卷数据科学和其他行业。它是一种非常快速且通用的格式,不仅可以用于存储许多数据结构,还可以用作关系数据库的替代品。
为了结束这段插曲,让我们只提一下,如果您正在使用 BSON 和 MessagePack 等二进制格式来存储/交换大量信息,您可能非常想看看 HDF5。
出现的一种模式是,BSON 在序列化时可能比 JSON 更昂贵,但在反序列化时更快;并且 MessagePack 在任何操作上都比两者都快。此外,由于其开销,尽管是二进制格式,但在存储非二进制数据时,BSON 文件有时可能比 JSON 文件更大。一些可以参考的链接:
还值得注意的是,即使对于相同的格式,性能也可能取决于您选择的序列化器和解析器。
虽然听起来很傻,但 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 和 YAML 都是数据序列化格式,但它们有一些关键区别。JSON 是 JavaScript 的一个子集,由于其与 JavaScript 的兼容性,因此经常在 Web 应用程序中使用。它使用简单的语法,易于阅读和编写。但是,它缺少一些功能,例如注释和多行字符串。另一方面,YAML 是 JSON 的超集,并且具有更人性化的语法。它支持注释和多行字符串,使其更易于用作配置文件。但是,它比 JSON 更复杂,并且支持度不如 JSON 广泛。
BSON 或二进制 JSON 是 JSON 类文档的二进制表示。它旨在在空间上高效,而且在计算密集型场景(如网络传输)中也是如此。BSON 可以存储比 JSON 更多的数据类型,包括二进制和日期数据类型。但是,它不如 JSON 或 YAML 人类可读,并且主要用于 MongoDB 中存储和检索数据。
MessagePack 是一种类似于 JSON 但更高效的二进制序列化格式。它紧凑、快速,并支持各种数据类型。它经常用于对性能要求很高的应用程序中,例如实时流式应用程序。但是,与 BSON 一样,它不如 JSON 或 YAML 人类可读。
是的,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中文网其他相关文章!