PostgreSQL教程 -》数据类型 -》JSON 类型
最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!
我要咨询根据RFC 7159 中的说明,JSON 数据类型是用来存储 JSON(JavaScript Object Notation) 数据的。这种数据也可以被存储为text,但是 JSON 数据类型的 优势在于能强制要求每个被存储的值符合 JSON 规则。也有很多 JSON 相关的函 数和操作符可以用于存储在这些数据类型中的数据,见 第 9.15 节。
PostgreSQL 提供存储JSON数据的两种类型:json 和 jsonb。 为了实现这些数据类型高效的查询机制, PostgreSQL还在第 8.14.6 节中提供了jsonpath数据类型描述。
json 和 jsonb数据类型接受几乎完全相同的值集合作为输入。 主要的实际区别之一是效率。json数据类型存储输入文本的精准拷贝,处理函数必须在每 次执行时必须重新解析该数据。而jsonb数据被存储在一种分解好的 二进制格式中,它在输入时要稍慢一些,因为需要做附加的转换。但是 jsonb在处理时要快很多,因为不需要解析。jsonb也支 持索引,这也是一个令人瞩目的优势。
由于json类型存储的是输入文本的准确拷贝,其中可能会保留在语法 上不明显的、存在于记号之间的空格,还有 JSON 对象内部的键的顺序。还有, 如果一个值中的 JSON 对象包含同一个键超过一次,所有的键/值对都会被保留( 处理函数会把最后的值当作有效值)。相反,jsonb不保留空格、不 保留对象键的顺序并且不保留重复的对象键。如果在输入中指定了重复的键,只有 最后一个值会被保留。
通常,除非有特别特殊的需要(例如遗留的对象键顺序假设),大多数应用应该 更愿意把 JSON 数据存储为jsonb。
PostgreSQL对每个数据库只允许一种 字符集编码。因此 JSON 类型不可能严格遵守 JSON 规范,除非数据库编码 是 UTF8。尝试直接包括数据库编码中无法表示的字符将会失败。反过来,能 在数据库编码中表示但是不在 UTF8 中的字符是被允许的。
RFC 7159 允许 JSON 字符串包含\uXXXX 所标记的 Unicode 转义序列。在json类型的输入函数中,不管数据库 编码如何都允许 Unicode 转义,并且只检查语法正确性(即,跟在\u 后面的四个十六进制位)。但是,jsonb的输入函数更加严格:它不允 许非 ASCII 字符的 Unicode 转义(高于U+007F的那些),除非数据 库编码是 UTF8。jsonb类型也拒绝\u0000(因为 PostgreSQL的text类型无法表示 它),并且它坚持使用 Unicode 代理对来标记位于 Unicode 基本多语言平面之外 的字符是正确的。合法的 Unicode 转义会被转换成等价的 ASCII 或 UTF8 字符进 行存储,这包括把代理对折叠成一个单一字符。
注意
很多第 9.15 节中描述的 JSON 处理函数将把 Unicode 转义转换成常规字符,并且将因此抛出和刚才所描述的同样类型的错误(即使它们 的输入是类型json而不是jsonb)。json的 输入函数不做这些检查是由来已久的,不过它确实允许将 JSON Unicode 转义简单 的(不经处理)存储在一个非 UTF8 数据库编码中。通常,最好尽可能避免在一个非 UTF8 数据库编码的 JSON 中混入 Unicode 转义。
在把文本 JSON 输入转换成jsonb时,RFC 7159描述 的基本类型会被有效地映射到原生的 PostgreSQL类型(如 表 8.23中所示)。因此,在合法 jsonb数据的组成上有一些次要额外约束,它们不适合 json类型和抽象意义上的 JSON,这些约束对应于有关哪些东西不 能被底层数据类型表示的限制。尤其是,jsonb将拒绝位于 PostgreSQL numeric数据类型范 围之外的数字,而json则不会。这类实现定义的限制是 RFC 7159 所允许的。不过,实际上这类问题更可能发生在其他实 现中,因为把 JSON 的number基本类型表示为 IEEE 754 双精度浮点 是很常见的(这也是RFC 7159 明确期待和允许的)。当在这类系 统间使用 JSON 作为一种交换格式时,应该考虑丢失数字精度的风险。
相反地,如表中所述,有一些 JSON 基本类型输入格式上的次要限制并不适用于相 应的PostgreSQL类型。
表 8.23. JSON 基本类型和相应的PostgreSQL类型
JSON 基本类型 PostgreSQL类型 注释
string text 不允许\u0000,如果数据库编码不是 UTF8,非 ASCII Unicode 转义也是这样
number numeric 不允许NaN 和 infinity值
boolean boolean 只接受小写true和false拼写
null (无) SQL NULL是一个不同的概念