【问题标题】:Binary JSON format that supports traversal支持遍历的二进制 JSON 格式
【发布时间】:2020-06-14 03:17:21
【问题描述】:

有谁知道一种序列化格式:

  1. 是二进制的,至少相对紧凑,
  2. 可以存储 JSON 样式的数据(不是 Protobuf、Thrift 等),
  3. 支持遍历(即您无需解析整个文档即可读取其中的一部分),并且
  4. 支持大文件(例如 30 GB)?

我看过以下内容:

  • CBOR - 不支持遍历
  • MessagePack - 不支持遍历
  • UBJSON - 不支持遍历
  • 微笑 - 不支持遍历

  • BSON - 支持遍历!但最大文档大小为 2 GB。

BSON 非常接近,但最大文件大小对我来说是致命的。有没有可以工作的格式?显然我可以自己写,但是二进制 JSON 格式实在是太多了,肯定有人做出了不错的吗?

编辑:“遍历”我的意思与the BSON authors mean 相同——您应该能够找到给定对象而无需解析整个文件。亚马逊称之为“稀疏”或“浅层”阅读。

【问题讨论】:

  • 您能否详细说明“遍历”和“不需要解析整个文档”的含义。您实际上是指“随机访问”吗?所有可反序列化的数据格式都将支持对数据的访问,而无需将整个事物作为反序列化保存在内存中,但它们通常依赖于从一开始就读取数据,因为没有随机访问索引告诉反序列化器事物在哪里。请准确说明您要查找的内容。
  • 已澄清。 “随机访问”仅适用于数据序列,而 JSON 不是,因此它不是完全正确的术语,但它基本上是正确的想法。当然,所有格式都允许您丢弃已解析的数据 - 这就是为什么我说您不需要解析整个文档。
  • 不,但也不完全准确。您在提供的答案中提到了具有长度前缀二进制文件的格式,我假设为字符串。在 BSON 类型的事物的意义上,这意味着您可能不必解析字符串来处理诸如转义字符等之类的事情,您可以直接跳过字节,但是这样的字符串的二进制编码可能会'当它从文本格式转换为二进制时,已经完成了这种处理。
  • 在BSON支持遍历的意义上,那么我想说所有数据格式都支持遍历,因为它们支持完全反序列化。部分反序列化/内存处理将是反序列化代码的属性,而不是格式的属性。换句话说,CBOR 不支持遍历的事实意味着支持 CBOR 的已知库不支持遍历,但应该可以创建这样的支持。可能比它的价值更多的工作,我会给你。
  • 另外,我不确定 2GB 是 BSON 的实际限制,但它是内部属性的限制。所以任何单个字符串都不能大于 2GB,但我不确定该限制是否适用于整个文档,但是我不会将 BSON 用于这种大数据,所以我不确定我是否知道所有内容关于这个。

标签: json serialization bson json-serialization cbor


【解决方案1】:

找到一个! Amazon IonFrom the FAQ:

许多读取是浅的或稀疏的,这意味着应用程序只关注流中值的子集,并且它可以快速确定是否需要完全实现某个值。

本着这些原则的精神,Ion 规范包括使 Ion 的二进制编码比其他无模式格式更易于阅读的功能。这些功能包括二进制值的长度前缀和 Ion 对符号表的使用。

关于 Ion 的简要说明:

  • 似乎设计得比较好。
  • 所有值都经过 TLV 编码,这使得它可以遍历(耶!)
  • 长度值不限于 32 位(是的!)
  • 它具有比 JSON 稍微丰富的对象模型,例如它支持时间戳、二进制数据、类型注释和 S 表达式(不知道为什么)。
  • 它支持符号表,因此可以对字段名进行实习!这意味着它可能明显比所有其他二进制 JSON 格式更紧凑。

它不是很受欢迎。库仅适用于几种语言,我什至找不到使用它的命令行工具。不过,如果您想要这些功能,它似乎是唯一的选择!

编辑:

最后我们选择了非常出色的 SQLite。它并没有真正遵循 JSON 数据模型,但它确实让您可以非常轻松地进行稀疏读取,而且速度非常快。另一种可能性是 DuckDB,它是 SQLite 的一种现代版本,但支持较少。

【讨论】:

    【解决方案2】:

    对于CBOR,我和你有类似的要求;对我来说不受 30GB 的限制是由无限的惰性列表解决的,并且没有单个对象大于 16MB(我只需要 TB 的“中等”大小的块 - 当然,您的要求可能会有所不同)。

    但是,通过简单的“可遍历”,有一个定义嵌套 CBOR 的 TAG。解码时,您将标签视为不存在。以这种方式你可以拥有

    { "key1" : [cbor-tag] <<binary-cbor-subtree>>,
      "key2" : [cbor-tag] <<binary-cbor-subtree>>
    }
    

    以这种方式,您将“跳过”“值”作为单个解码+搜索,但如果您只是执行 cbor-to-json,则解析器必须将标记的二进制文件解码为 CBOR。因此您将获得两全其美(BSON 与 CBOR)既可流式传输(通过无限映射 len)又可遍历。

    当然这需要专门的编码器,但至少解码器应该是普通的/标准的。

    对我们来说,我们碰巧使用了能够识别标记二进制值的专用编码器/解码器(因为我们需要维护一个包含潜在巨大值的多 GB 映射)。

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多