Answers:
首先,hstore
是一个contrib模块,它仅允许您存储key => value对,其中key和value只能是text
s(但是值也可以是sql NULL
s)。
两者json
&都jsonb
允许您存储有效的JSON 值(在其spec中定义)。
F.ex. 这些都是有效的JSON表示:null
,true
,[1,false,"string",{"foo":"bar"}]
,{"foo":"bar","baz":[null]}
- hstore
相比有什么JSON能够只是一个小的子集(但如果你只需要这个子集,它的罚款)。
json
&之间的唯一区别jsonb
是它们的存储:
json
以其纯文本格式存储,而jsonb
以某种二进制表示形式存储这有3个主要结果:
jsonb
通常要花费比json
(有时不是)更多的磁盘空间来存储jsonb
从其输入表示构建所需的时间比 json
json
操作采取显著的时间比jsonb
(也分析必须在每一个你做一些工作时间进行json
类型化值)当jsonb
将有稳定版本发布时,将有两个主要用例,您可以在它们之间轻松选择:
json
。jsonb
。jsonb
不支持它呢?UPDATE test SET data->'a' = 123 WHERE id = 1;
从CREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
json
以上jsonb
是如果遗留原因代码消耗的json
依赖于的排序json
字段,它们不能被重新排序。
text
vs json
:后者带有JSON验证,因此,在无效JSON时,它只会在插入时失败,而不是在您的应用程序每次读取它时都会失败(因为它得到了无效的表示)。同样,您可以安全地将后者转换jsonb
为数据库中的内容。
一个简单的解释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)
更多有关jsonb开发人员的演讲视频和幻灯片演示。他们还引入了JsQuery,pg.extension提供了强大的jsonb查询语言
hstore
更像是“宽列”存储类型,它是键-值对的平面(非嵌套)字典,始终以合理有效的二进制格式(哈希表,因此是名称)存储。json
将JSON文档存储为文本,在存储文档时执行验证,并在需要时在输出中解析它们(即访问单个字段);它应该支持整个JSON规范。由于存储了整个JSON文本,因此将保留其格式。jsonb
出于性能原因而采取捷径:JSON数据在输入时进行解析,并以二进制格式存储,字典中的键顺序不予维护,也不是重复的键。访问JSONB字段中的单个元素很快,因为它不需要一直解析JSON文本。在输出时,将重建JSON数据,并且会丢失初始格式。IMO,如果您使用的是机器可读数据,则没有重要的理由不使用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)
通常,除非有特殊需要,例如关于对象键顺序的传统假设,否则应该首选JSONB。
我今天在pgopen上,基准测试速度比mongodb快得多,我相信选择速度要快500%。与mongodb相比,几乎所有东西都至少快了200%,而现在的一个例外是更新,它需要完全重写整个json列,而mongodb处理得更好。
jsonb上的杜松子酒索引听起来很棒。
而且postgres会在内部保留jsonb类型,并且基本上将其与数字,文本,布尔值等类型匹配。
也可以使用jsonb加入
为存储过程添加PLv8,对于node.js开发人员来说,这基本上是梦想成真。
由于它以二进制jsonb的形式存储,因此也会删除所有空白,更改属性的顺序,并使用属性的最后一次出现删除重复的属性。
除了在查询与json列相反的jsonb列时使用索引之外,postgres不必实际运行将文本转换为json的功能,这可能会节省大量的时间。
关于json
和jsonb
数据类型之间的区别,值得一提的是官方解释:
PostgreSQL提供两种存储JSON数据的类型:
json
和jsonb
。为了对这些数据类型实现有效的查询机制,PostgreSQL还提供了8.14.6 节中描述的jsonpath数据类型。。该
json
和jsonb
数据类型接受值作为输入的几乎相同的集。实际的主要区别是效率之一。该json
数据类型存储所输入的文本,该文本处理功能必须在每次执行时重新分析的精确副本; 而jsonb
数据被存储在一个分解的二进制格式,使得它稍微慢于输入由于添加转换开销,但显著更快的过程,因为不需要重新解析。jsonb
还支持索引编制,这可能是一个很大的优势。因为
json
类型存储了输入文本的精确副本,所以它将保留标记之间语义上无关紧要的空白以及JSON对象中键的顺序。此外,如果值中的JSON对象包含相同的键不止一次,则所有键/值对都会保留。(处理功能将最后一个值视为可操作值。)相比之下,jsonb
不保留空格,不保留对象键的顺序,也不保留重复的对象键。如果在输入中指定了重复的键,则仅保留最后一个值。通常,大多数应用程序应该将JSON数据存储为
jsonb
,除非有非常特殊的需求,例如关于对象键顺序的传统假设。PostgreSQL每个数据库只允许一种字符集编码。因此,除非数据库编码为UTF8,否则JSON类型不可能严格符合JSON规范。尝试直接包含数据库编码中无法表示的字符将失败;相反,将允许使用可以在数据库编码中表示但不能以UTF8表示的字符。
来源:https : //www.postgresql.org/docs/current/datatype-json.html
据我所知,
当前存在的hstore(在PostgreSQL 9.3中)不允许嵌套其他对象和数组作为其键/值对的值。但是,将来的hstore修补程序将允许嵌套。此修补程序将不在9.4版本中,并且可能很快将不包含在内。
JSON,因为它目前存在确实允许嵌套,但基于文本的,并且不允许索引,因此它是“慢”
随9.4版本一起发布的jsonb将具有json的当前嵌套功能,以及hstore的GIN / GIST索引,因此速度很快
使用PostgreSQL 9.4的人们似乎在说,新的快速jsonb类型将吸引那些选择使用像MongoDB这样的noSQL数据存储的人,但是现在可以将关系数据库与可查询的非结构化数据结合在一起
http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html
Postgresql 9.4 jsonb的基准似乎与MongoDB相当或在某些情况下比MongoDB更快
http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb