JSON数据类型操作__快速入门_云数据库 HybridDB-阿里云
JSON类型几乎已成为互联网及物联网(IoT)的基础数据类型,其重要性不言而喻,具体协议请参考官网。
PostgreSQL对JSON的支持已经比较完善,阿里云深度优化云数据库HybridDB,基于PostgreSQL语法进行了JSON数据类型的支持。
检查现有版本是否支持JSON
首先,先来看看是否已经支持了JSON,可以通过下面的命令:
=> SELECT '""'::json;
json
------
""
(1 row)
这说明已经支持了JSON的类型,可以使用了,如果执行不成功,请[重新启动实例]。如果报下面这个,则是未支持:
=> SELECT '""'::json;
ERROR: type "json" does not exist
LINE 1: SELECT '""'::json;
^
上面的命令很简单,是一次从字符串到JSON格式的强制转换,这也基本上是其操作上的本质。
JSON在数据库中的转换
数据库的操作主要分为读和写,JSON的写一般是数据库中的字符串到JSON,但字符串中的内容支持是比较标准的,支持JSON标准中包括字符串、数字、数组、对象等所有内容。如:
- 字符串
=> SELECT '"hijson"'::json;
json
-------
"hijson"
(1 row)
“::”在PostgreSQL/Greenplum/HybridDB代表着强制类型转换。在此转换的时候,会调用JSON类型的输入函数,因此,类型转换的时候同样会做JSON格式的检查:
=> SELECT '{hijson:1024}'::json;
ERROR: invalid input syntax for type json
LINE 1: SELECT '{hijson:1024}'::json;
^
DETAIL: Token "hijson" is invalid.
CONTEXT: JSON data, line 1: {hijson...
=>
这里的””是必不可少的,原因是在标准中,KEY值对应的是一个字符串。因此在语法上会报错。
除了类型上的强制转换,还有的就是从数据库记录到JSON串的转换。
我们正常使用JSON,不会只用一个String或一个Number,而往往是一个对象,对象中包含一个或多个键值对。那么,对GP来说,支持到对象的转换,即支持了JSON的绝大多数场景,如:
=> select row_to_json(row('{"a":"a"}', 'b'));
row_to_json
---------------------------------
{"f1":"{"a":"a"}","f2":"b"}
(1 row)
=> select row_to_json(row('{"a":"a"}'::json, 'b'));
row_to_json
---------------------------
{"f1":{"a":"a"},"f2":"b"}
(1 row)
由此也可以看出字符串和JSON的区别,这样就可以很方便地将一整条记录转换成JSON。
JSON内部数据类型的定义
- 对象
对象是JSON中最常用的,如:
=> select '{"key":"value"}'::json;
json
-----------------
{"key":"value"}
(1 row)
- 整数 & 浮点数
JSON的协议只有三种数字:整数、浮点数、常数表达式,当前GP对这三种都有很好的支持。
=> SELECT '1024'::json;
json
------
1024
(1 row)
=> SELECT '0.1'::json;
json
------
0.1
(1 row)
特殊的,你可能需要这个:
=> SELECT '1e100'::json;
json
-------
1e100
(1 row)
=> SELECT '{"f":1e100}'::json;
json
-------------
{"f":1e100}
(1 row)
并且,包括下面这个长度超长的数字:
=> SELECT '9223372036854775808'::json;
json
---------------------
9223372036854775808
(1 row)
- 数组
=> SELECT '[[1,2], [3,4,5]]'::json;
json
------------------
[[1,2], [3,4,5]]
(1 row)
操作符
- JSON支持操作符种类
=> select oprname,oprcode from pg_operator where oprleft = 3114;
oprname | oprcode
---------+---------------------------
-> | json_object_field
->> | json_object_field_text
-> | json_array_element
->> | json_array_element_text
#> | json_extract_path_op
#>> | json_extract_path_text_op
(6 rows)
- 基本使用方法
=> SELECT '{"f":"1e100"}'::json -> 'f';
?column?
----------
"1e100"
(1 row)
=> SELECT '{"f":"1e100"}'::json ->> 'f';
?column?
----------
1e100
(1 row)
=> select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f4','f6'];
?column?
-----------
"stringy"
(1 row)
=> select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>'{f4,f6}';
?column?
-----------
"stringy"
(1 row)
=> select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>'{f2,0}';
?column?
----------
f3
(1 row)
JSON函数
- 支持的函数
postgres=# df *json*
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------------------+------------------+-----------------------------------------------------------+--------
pg_catalog | array_to_json | json | anyarray | normal
pg_catalog | array_to_json | json | anyarray, boolean | normal
pg_catalog | json_array_element | json | from_json json, element_index integer | normal
pg_catalog | json_array_element_text | text | from_json json, element_index integer | normal
pg_catalog | json_array_elements | SETOF json | from_json json, OUT value json | normal
pg_catalog | json_array_length | integer | json | normal
pg_catalog | json_each | SETOF record | from_json json, OUT key text, OUT value json | normal
pg_catalog | json_each_text | SETOF record | from_json json, OUT key text, OUT value text | normal
pg_catalog | json_extract_path | json | from_json json, VARIADIC path_elems text[] | normal
pg_catalog | json_extract_path_op | json | from_json json, path_elems text[] | normal
pg_catalog | json_extract_path_text | text | from_json json, VARIADIC path_elems text[] | normal
pg_catalog | json_extract_path_text_op | text | from_json json, path_elems text[] | normal
pg_catalog | json_in | json | cstring | normal
pg_catalog | json_object_field | json | from_json json, field_name text | normal
pg_catalog | json_object_field_text | text | from_json json, field_name text | normal
pg_catalog | json_object_keys | SETOF text | json | normal
pg_catalog | json_out | cstring | json | normal
pg_catalog | json_populate_record | anyelement | base anyelement, from_json json, use_json_as_text boolean | normal
pg_catalog | json_populate_recordset | SETOF anyelement | base anyelement, from_json json, use_json_as_text boolean | normal
pg_catalog | json_recv | json | internal | normal
pg_catalog | json_send | bytea | json | normal
pg_catalog | row_to_json | json | record | normal
pg_catalog | row_to_json | json | record, boolean | normal
pg_catalog | to_json | json | anyelement | normal
(24 rows)
- 基本使用方法
=> SELECT array_to_json('{{1,5},{99,100}}'::int[]);
array_to_json
------------------
[[1,5],[99,100]]
(1 row)
=> SELECT row_to_json(row(1,'foo'));
row_to_json
---------------------
{"f1":1,"f2":"foo"}
(1 row)
=> SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]');
json_array_length
-------------------
5
(1 row)
=> select * from json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q;
key | value
-----+-----------
f1 | [1,2,3]
f2 | {"f3":1}
f4 | null
f5 | 99
f6 | "stringy"
(5 rows)
=> select json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}');
json_each_text
-------------------
(f1,"[1,2,3]")
(f2,"{""f3"":1}")
(f4,)
(f5,null)
(4 rows)
=> select json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]');
json_array_elements
-----------------------
1
true
[1,[2,3]]
null
{"f1":1,"f2":[7,8,9]}
false
(6 rows)
create type jpop as (a text, b int, c timestamp);
=> select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}', false) q;
a | b | c
--------+---+---
blurfl | |
(1 row)
=> select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q;
a | b | c
--------+---+--------------------------
blurfl | |
| 3 | Fri Jan 20 10:42:53 2012
(2 rows)
完整操作事例
- 创建表
create table tj(id serial, ary int[], obj json, num integer);
=> insert into tj(ary, obj, num) values('{1,5}'::int[], '{"obj":1}', 5);
INSERT 0 1
=> select row_to_json(q) from (select id, ary, obj, num from tj) as q;
row_to_json
-------------------------------------------
{"f1":1,"f2":[1,5],"f3":{"obj":1},"f4":5}
(1 row)
=> insert into tj(ary, obj, num) values('{2,5}'::int[], '{"obj":2}', 5);
INSERT 0 1
=> select row_to_json(q) from (select id, ary, obj, num from tj) as q;
row_to_json
-------------------------------------------
{"f1":1,"f2":[1,5],"f3":{"obj":1},"f4":5}
{"f1":2,"f2":[2,5],"f3":{"obj":2},"f4":5}
(2 rows)
- 多表JOIN
create table tj2(id serial, ary int[], obj json, num integer);
=> insert into tj2(ary, obj, num) values('{2,5}'::int[], '{"obj":2}', 5);
INSERT 0 1
=> select * from tj, tj2 where tj.obj->>'obj' = tj2.obj->>'obj';
id | ary | obj | num | id | ary | obj | num
----+-------+-----------+-----+----+-------+-----------+-----
2 | {2,5} | {"obj":2} | 5 | 1 | {2,5} | {"obj":2} | 5
(1 row)
=> select * from tj, tj2 where json_object_field_text(tj.obj, 'obj') = json_object_field_text(tj2.obj, 'obj');
id | ary | obj | num | id | ary | obj | num
----+-------+-----------+-----+----+-------+-----------+-----
2 | {2,5} | {"obj":2} | 5 | 1 | {2,5} | {"obj":2} | 5
(1 row)
- JSON函数索引
CREATE TEMP TABLE test_json (
json_type text,
obj json
);
=> insert into test_json values('aa', '{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}');
INSERT 0 1
=> insert into test_json values('cc', '{"f7":{"f3":1},"f8":{"f5":99,"f6":"foo"}}');
INSERT 0 1
=> select obj->'f2' from test_json where json_type = 'aa';
?column?
----------
{"f3":1}
(1 row)
=> create index i on test_json (json_extract_path_text(obj, '{f4}'));
CREATE INDEX
=> select * from test_json where json_extract_path_text(obj, '{f4}') = '{"f5":99,"f6":"foo"}';
json_type | obj
-----------+-------------------------------------------
aa | {"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}
(1 row)
遗撼的是,JSON类型暂时不能支持作为分布键来使用;也不支持JSON聚合函数;
下面是Python访问的一个例子:
#! /bin/env python
import time
import json
import psycopg2
def gpquery(sql):
conn = None
try:
conn = psycopg2.connect("dbname=sanity1x2")
conn.autocommit = True
cur = conn.cursor()
cur.execute(sql)
return cur.fetchall()
except Exception as e:
if conn:
try:
conn.close()
except:
pass
time.sleep(10)
print e
return None
def main():
sql = "select obj from tj;"
#rows = Connection(host, port, user, pwd, dbname).query(sql)
rows = gpquery(sql)
for row in rows:
print json.loads(row[0])
if __name__ == "__main__":
main()
最后更新:2016-12-11 20:56:22
上一篇:
客户端工具使用__快速入门_云数据库 HybridDB-阿里云
下一篇:
云数据库HybridDB 服务协议__服务条款_云数据库 HybridDB-阿里云
对接个性化推荐__快速开始_移动数据分析-阿里云
CDN使用JAVA API刷新缓存方法__运维技术分享_技术运维问题_CDN-阿里云
VirtualMFADevice__数据类型_RAM API文档_访问控制-阿里云
BandwidthPackageSetType__数据类型_API 参考_云服务器 ECS-阿里云
属性值类型__语义表示协议_自然语言理解(NLU)_智能语音交互-阿里云
Endpoint签名认证__调用方式_API使用手册_消息服务-阿里云
修改共享带宽包-增加公网IP__NAT网关相关接口_API 参考_云服务器 ECS-阿里云
启停服务__服务管理_用户指南_容器服务-阿里云
BGP高防是什么?有什么优势?__接入指导_产品常见问题_DDoS 高防IP-阿里云
使用 DTS 迁移 PPAS 数据__快速入门(PPAS)_云数据库 RDS 版-阿里云
相关内容
常见错误说明__附录_大数据计算服务-阿里云
发送短信接口__API使用手册_短信服务-阿里云
接口文档__Android_安全组件教程_移动安全-阿里云
运营商错误码(联通)__常见问题_短信服务-阿里云
设置短信模板__使用手册_短信服务-阿里云
OSS 权限问题及排查__常见错误及排除_最佳实践_对象存储 OSS-阿里云
消息通知__操作指南_批量计算-阿里云
设备端快速接入(MQTT)__快速开始_阿里云物联网套件-阿里云
查询API调用流量数据__API管理相关接口_API_API 网关-阿里云
使用STS访问__JavaScript-SDK_SDK 参考_对象存储 OSS-阿里云