说明PostgreSQL引入的JSONB

PostgreSQL刚刚在9.4版中引入了JSONB,并且已经有了关于黑客新闻的趋势。它与之前在PostgreSQL中出现的Hstore和JSON有什么不同?

它的优点和局限性是什么?什么时候应该考虑使用它?

183800 次浏览

Peeyush:

简单的回答是:

  • 如果你正在做很多JSON操作内部 PostgreSQL,如排序,切片,拼接等,你应该使用JSONB速度的原因。
  • 如果需要对JSON上的任意键搜索进行索引查找,那么应该使用JSONB。
  • 如果以上两种方法都不使用,则可能应该使用JSON。
  • 如果需要保留键顺序、空格和重复的键,则应该使用JSON。

想要得到更长的答案,你需要等我在9.4发行版之前写一篇完整的“HowTo”文章。

  • hstore更像是一种“宽列”存储类型,它是键-值对的平面(非嵌套)字典,总是以一种相当有效的二进制格式存储(哈希表,因此得名)。
  • json将JSON文档存储为文本,在存储文档时执行验证,并在需要时对输出进行解析(即访问单个字段);它应该支持整个JSON规范。由于整个JSON文本被存储,它的格式被保留。
  • jsonb出于性能原因采取了快捷方式:JSON数据在输入时被解析并以二进制格式存储,字典中的键顺序不被维护,重复键也不被维护。访问JSONB字段中的单个元素非常快,因为它不需要一直解析JSON文本。在输出时,JSON数据被重构,初始格式丢失。

在我看来,如果你处理的是机器可读的数据,那么一旦可用,就没有重要的理由使用jsonb

首先,hstore是一个contrib模块,它只允许你存储key =>值对,其中键和值只能是__abc1(但是值也可以是sql NULLs)。

json &jsonb允许你存储一个有效的JSON 价值(在它的规范中定义)。

F.ex。这些是有效的JSON表示:nulltrue[1,false,"string",{"foo":"bar"}]{"foo":"bar","baz":[null]} - hstore与JSON的能力相比只是一个小子集(但如果你只需要这个子集,也没关系)。

json和amp;jsonb是它们的存储:

  • json以纯文本格式存储,而
  • jsonb以二进制形式存储

这有3个主要后果:

  • jsonb通常比json占用更多的磁盘空间(有时不是)
  • json相比,jsonb从其输入表示中构建需要更多的时间
  • json操作比jsonb (&解析也需要在每次对json类型的值进行操作时进行)

jsonb的稳定版本可用时,会有两个主要的用例,你可以很容易地在它们之间进行选择:

  1. 如果你只在你的应用程序中使用JSON表示,PostgreSQL只用于存储&如果要获取此表示形式,则应该使用json
  2. 如果你在PostgreSQL中对JSON值做了很多操作,或者对一些JSON字段使用索引,你应该使用jsonb

据我所知

  • hstore,因为它目前存在(在PostgreSQL 9.3中)不允许嵌套其他对象和数组作为它的键/值对的值。然而,未来的hstore补丁将允许嵌套。这个补丁不会出现在9.4版本中,也可能不会很快被包括在内。

  • 允许嵌套,但它是基于文本的,不允许索引,因此它是&;慢&;

  • 随着9.4发布的jsonb将拥有当前json的嵌套功能,以及hstore的GIN/GIST索引,所以它会很快

在PostgreSQL 9.4工作的人似乎在说,新的、快速的jsonb类型将吸引那些选择使用NoSQL数据存储(如MongoDB)的人,但它现在可以将关系数据库和可查询的非结构化数据组合在一个框架下

为什么HStore2/jsonb是9.4最重要的补丁

PostgreSQL 9.4 jsonb的基准测试似乎与MongoDB相当,在某些情况下甚至比MongoDB更快。

< a href = " http://texture。Io /alphabetum/postgresql- include -hstore-vs-mongodb" rel="nofollow noreferrer">http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb .

我今天在PostgresOpen,基准测试比MongoDB快得多。我相信它的选择速度快了500%。几乎所有东西都更快,与MongoDB相比至少快了200%。现在的一个例外是需要完全重写整个JSON列的更新——这一点MongoDB处理得更好。

JSONB上的gin索引听起来很棒。

PostgreSQL还将在内部持久化JSONB类型,并将其与数字、文本、布尔等类型进行匹配。

使用JSONB也可以实现连接。

为存储过程添加PLv8,这基本上将是node . js开发人员的梦想成真。

由于它被存储为二进制,JSONB还将删除所有空白,改变属性的顺序,并使用属性的最后一次出现来删除重复的属性。

除了索引,当查询JSONB列和JSON列时,PostgreSQL不需要实际运行将每一行的文本转换为JSON的功能,这可能会节省大量的时间。

json和jsonb (原始图片由PostgresProfessional提供)区别的简单解释:

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;


json          |        jsonb
------------------------+---------------------
{"c":0,   "a":2,"a":1} | {"a": 1, "c": 0}
(1 row)
  • Json:文本存储«as is»
  • Jsonb:没有空格
  • 没有重复的键,最后一个键获胜
  • Jsonb:键排序

更多内容在jsonb开发人员的演讲视频幻灯片演示中。他们还引入了JsQuery,一个pg.扩展,提供了强大的jsonb查询语言。

JSONB是一个“更好的”;JSON的版本。

让我们来看一个例子:

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;
          json          |        jsonb
------------------------+---------------------
{"c":0,   "a":2,"a":1} | {"a": 1, "c": 0}
(1 row)
  1. JSON存储空白,这就是为什么当键"a"存储,而JSONB不存储。
  2. JSON存储键的所有值。这就是为什么你可以看到多个值(2和1)对应键"a",而JSONB只“;stores"最后一个值。
  3. JSON维护元素插入的顺序,而JSONB维护&;秩序。
  4. JSONB对象存储为解压缩的二进制文件,而不是“原始数据”。在JSON中,在检索过程中不需要重新解析数据。
  5. JSONB还支持索引,这可能是一个显著的优势。

一般来说,应该更喜欢JSONB,除非有特殊的需要,比如对对象键的顺序有遗留的假设。

另一个重要的区别,在上面的回答中没有提到,是json类型没有相等操作符,但jsonb有。

这意味着当你从表中选择这个json-type和/或其他字段时,你不能使用DISTINCT关键字(你可以使用DISTINCT ON代替,但由于像这样的情况,这并不总是可能的)。

关于jsonjsonb数据类型之间的差异,值得一提的是官方解释:

PostgreSQL提供了两种类型来存储JSON数据:jsonjsonb。来 实现这些数据类型的高效查询机制,PostgreSQL 还提供了部分8.14.6中描述的jsonpath数据类型 jsonjsonb数据类型接受几乎相同的值集 作为输入。主要的实际差别在于效率。的 json数据类型存储输入文本的精确副本 处理函数必须在每次执行时重新解析;而jsonb数据 存储在分解的二进制格式,使它稍慢 由于增加了转换开销,但要快得多 过程,因为不需要重新解析。jsonb也支持索引, 这是一个显著的优势。

因为json类型存储输入文本的精确副本,所以它将 在标记之间保留语义上无关紧要的空白,例如 以及JSON对象中键的顺序。同样,如果是JSON对象 值中多次包含相同键的,则所有 键/值对被保留。(处理函数考虑最后一种情况 值作为运算值。)相比之下,jsonb不保存 空白,不会保留对象键的顺序,也不会 保留重复的对象键。属性中指定了重复的键

.输入时,只保留最后一个值 一般来说,大多数应用程序应该倾向于将JSON数据存储为 jsonb,除非有相当特殊的需求,比如遗留 关于对象键排序的假设。

PostgreSQL只允许每个数据库使用一种字符集编码。它是 因此,JSON类型不可能严格遵守 JSON规范,除非数据库编码为UTF8。尝试 直接包含数据库中不能表示的字符 编码将失败;相反,可以表示的字符 数据库编码,但不是UTF8将被允许

来源:https://www.postgresql.org/docs/current/datatype-json.html