JSON數據類型操作__快速入門_雲數據庫 HybridDB-阿裏雲
JSON類型幾乎已成為互聯網及物聯網(IoT)的基礎數據類型,其重要性不言而喻,具體協議請參考官網。
PostgreSQL對JSON的支持已經比較完善,阿裏雲深度優化雲數據庫HybridDB,基於PostgreSQL語法進行了JSON數據類型的支持。
檢查現有版本是否支持JSON
首先,先來看看是否已經支持了JSON,可以通過下麵的命令:
=> SELECT '""'::json;json------""(1 row)
這說明已經支持了JSON的類型,可以使用了,如果執行不成功,請[重新啟動實例]。如果報下麵這個,則是未支持:
=> SELECT '""'::json;ERROR: type "json" does not existLINE 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 jsonLINE 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 functionsSchema | Name | Result data type | Argument data types | Type------------+---------------------------+------------------+-----------------------------------------------------------+--------pg_catalog | array_to_json | json | anyarray | normalpg_catalog | array_to_json | json | anyarray, boolean | normalpg_catalog | json_array_element | json | from_json json, element_index integer | normalpg_catalog | json_array_element_text | text | from_json json, element_index integer | normalpg_catalog | json_array_elements | SETOF json | from_json json, OUT value json | normalpg_catalog | json_array_length | integer | json | normalpg_catalog | json_each | SETOF record | from_json json, OUT key text, OUT value json | normalpg_catalog | json_each_text | SETOF record | from_json json, OUT key text, OUT value text | normalpg_catalog | json_extract_path | json | from_json json, VARIADIC path_elems text[] | normalpg_catalog | json_extract_path_op | json | from_json json, path_elems text[] | normalpg_catalog | json_extract_path_text | text | from_json json, VARIADIC path_elems text[] | normalpg_catalog | json_extract_path_text_op | text | from_json json, path_elems text[] | normalpg_catalog | json_in | json | cstring | normalpg_catalog | json_object_field | json | from_json json, field_name text | normalpg_catalog | json_object_field_text | text | from_json json, field_name text | normalpg_catalog | json_object_keys | SETOF text | json | normalpg_catalog | json_out | cstring | json | normalpg_catalog | json_populate_record | anyelement | base anyelement, from_json json, use_json_as_text boolean | normalpg_catalog | json_populate_recordset | SETOF anyelement | base anyelement, from_json json, use_json_as_text boolean | normalpg_catalog | json_recv | json | internal | normalpg_catalog | json_send | bytea | json | normalpg_catalog | row_to_json | json | record | normalpg_catalog | row_to_json | json | record, boolean | normalpg_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 | nullf5 | 99f6 | "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-----------------------1true[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 pythonimport timeimport jsonimport psycopg2def gpquery(sql):conn = Nonetry:conn = psycopg2.connect("dbname=sanity1x2")conn.autocommit = Truecur = conn.cursor()cur.execute(sql)return cur.fetchall()except Exception as e:if conn:try:conn.close()except:passtime.sleep(10)print ereturn Nonedef 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-阿裏雲