JSONB vs. BSON:追踪 PostgreSQL 与 MongoDB 的 Wire 协议

发布: (2025年12月22日 GMT+8 04:27)
4 min read
原文: Dev.to

Source: Dev.to

概览

MongoDB 的 BSON 与 PostgreSQL 的 JSONB 之间存在本质区别。两者都是二进制 JSON 格式,但它们的角色不同。JSONB 纯粹是 PostgreSQL 中 JSON 数据的内部存储格式。BSON 则是 MongoDB 的原生数据格式:它被应用程序驱动用于与数据库通信,同时也作为磁盘上的存储格式。

关键区别

  • 目的
    • JSONB – 为 PostgreSQL 内部的存储和查询进行优化。
    • BSON – 为在 MongoDB 中的网络传输和磁盘存储而设计。
  • 数据类型
    • JSONB 支持 JSON 类型的子集(对象、数组、字符串、数字、布尔值、null)。
    • BSON 额外添加了诸如 ObjectIdDateBinaryDecimal128 等类型。
  • 大小开销
    • BSON 为类型信息和长度前缀保留了额外字节,使得相同数据下它的体积略大于 JSONB。
  • 索引
    • PostgreSQL 可以使用 GIN/GiST 索引对 JSONB 字段建立索引。
    • MongoDB 直接在 BSON 字段上提供索引。

跟踪 PostgreSQL Wire Protocol

PostgreSQL 使用自己的 wire protocol 与客户端通信。要检查原始消息:

# Using pg_recvlogical to capture logical replication messages
pg_recvlogical \
  --dbname=postgres \
  --slot=debug_slot \
  --start \
  --verbose

或使用 tcpdump

sudo tcpdump -i any -w pg.pcap port 5432

随后可以在 Wireshark 中打开捕获文件,并使用过滤器 postgresql 来解码协议消息。

跟踪 MongoDB Wire Protocol

MongoDB 使用 BSON wire protocol。捕获流量的一个简便方法是结合 mongodumptcpdump

# Capture traffic on default MongoDB port 27017
sudo tcpdump -i any -w mongo.pcap port 27017

在 Wireshark 中使用过滤器 mongodb 解码消息。你会看到诸如 OP_QUERYOP_INSERT 以及它们的 BSON 负载等操作。

示例:解码 BSON 文档

假设你捕获到了以下原始字节(十六进制):

16 00 00 00 02 66 6f 6f 00 04 00 00 00 62 61 72 00 00

解释:

偏移字节含义
0‑316 00 00 00文档长度(22 字节)
402类型:字符串
5‑766 6f 6f键:foo
800键的空字符终止符
9‑1204 00 00 00字符串长度(4)
13‑1562 61 72值:bar
1600值的空字符终止符
17‑2100 00 00 00文档结束标记

何时使用哪种格式

  • 使用 JSONB 当你在 PostgreSQL 中工作,需要强大的 SQL 查询能力、索引以及事务保证时。
  • 使用 BSON 当你与 MongoDB 交互,尤其是需要 MongoDB 特有的数据类型或想利用其灵活的模式和分片特性时。

理解 wire protocol 与底层二进制格式,有助于在调试性能问题、构建自定义驱动或仅仅是深入了解这些数据库在底层是如何运作时提供帮助。

Back to Blog

相关文章

阅读更多 »

大胆自行托管 Postgres

文章链接: https://pierce.dev/notes/go-ahead-self-host-postgresuser-content-fn-1 评论链接: https://news.ycombinator.com/item?id=46336947 积分: 7 评论...

索引与DBMS的崛起

你好,我是Maneshwar。我正在开发 FreeDevTools online https://hexmos.com/freedevtools,当前正打造一个汇集所有 dev tools、cheat codes 和 TLDRs 的统一平台。