数据格式的重要性:第1部分—当前状态问题


JSON是一种非常简单的格式。使用它、交换它、阅读它等都非常容易。以下是JSON格式的完整定义:

object = {} | { members }
members = pair | pair , members
pair = string : value
array = [] | [ elements ]
elements = value | value , elements
value = string | number | object | array | true | false | null

到目前为止,一切顺利。但是,JSON也有一些主要问题。特别是,JSON要求您在使用它之前阅读并解析整个文档(至少直到您真正关心的部分)。将JSON文档读入内存并实际使用它们意味着加载和解析整个文档,通常需要使用字典来快速访问数据。让我们看看这个典型的文档:

{
  "firstName": "John",
  "lastName": "Smith",
  "address": {
  "state": "NY",
  "postalCode": "10021-3100"
},
"children": [{"firstName": "Alice"}]
}

解析后在内存中会是什么样子?

Dictionary (root)
firstName –> John
lastName –> Smith
address –> Dictionary
state –> NY
postalCode –> 10021-3100
children –> array
[0] –> Dictionary
firstName –> Alice

所以,这是三个字典和一个数组(即使假设我们忽略了所有的字符串)。使用Newtonsoft.Json,上面的文档占用了3840字节的托管内存(在WinDBG中使用ObjSize测量)。文档的文本大小为126字节。大小不同的原因是字典。这里是320字节分配:

new Dictionary<string,Object>{ {“test”, “tube”} };

正如你所看到的,这种增长很快。对于一个主要处理JSON数据的数据库来说,这是一个非常重要的因素。控制内存是数据库工作的一个非常重要的方面。而且,JSON在这方面效率很低。例如,假设我们想通过孩子的名字来索引文档。这将迫使我们解析整个文档,从而导致CPU和内存的巨大损失。我们需要更好的内部数据格式。

在我的下一篇文章中,我将详细介绍这种格式,以及我们在哪些限制下工作。