MySQL中JSON数据类型详解

一、JSON简介

1. 什么是JSON

全称是JavaScript Object Notation,一种轻量级的数据交换格式

特点:简洁、清晰、灵活、易于阅读、直观

2. 如何表示

MySQL中JSON数据类型详解_第1张图片

最直观的是以key : value的形式表示

对象:用‘{}’eg:{“k1”: “value”, “k2”: 10}键值对形式存在

数组:用‘[]’eg:["abc", 10, null, true, false]

嵌套使用:[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]]

          {"k1": "value", "k2": [10, 20]}

  • 使用JSON数据类型要注意的事项:

1.JSON数据类型是有格式的,存储在JSON列中的JSON文档的自动验证 ,无效的文档会产生错误。

验证方法:

(1)JSON_VALID()

示例:select json_valid('{"a":1,"b":2}'),结果是1,证明{"a":1,"b":2}这个格式正确

(2) 百度 json格式化校验工具 https://www.sojson.com/

2.  Json列上没有默认值。

3. 不能在Json列上直接创建索引,可在虚拟列上创建索引。

4. 原生json数据类型是MySQL在融合非关系型数据库上作出的改进。

三、相关函数

1、创建函数

首先创建带JSON数据类型的表

create table t(id int,js json,PRIMARY KEY (`id`))

插入数据

insert into t values(1,'{"a":1,"s":"abc"}');

insert into t values(2,'[1,2,{"a":123}]');

insert into t values(3,'"str"');

insert into t values(4,'123');

除了上面的还可以用JSON_Array和JSON_Object函数来构造

#JSON_Object插入对象,自动转换成key – value的形式

insert into t values(5,JSON_Object('key1','蓝天','key2','白云'));

#JSON_Array插入数组,自动转换成数组

insert into t values(6,JSON_Array('你好','爱你','花朵'))

JSON_MERGE 将多个值合并

#数组合并

insert into t values(7,jSON_MERGE('[1,2]','[3,4]'))

#对象融合

insert into t values(8,jSON_MERGE('{"a":1}','{"b":2}'))

select JSON_MERGE('{"a":1}','{"b":2}')

#特殊的还是在数组,如果里面的两个数是变量,查询出来这两个数会变成常量

insert into t values(9,JSON_MERGE('123','45'))

#目标碰到数组,会先转换成数组[]

insert into t values(10,JSON_MERGE('{"a":1}','[4,5]'))

 

select jSON_MERGE('{"a":1}','[4,5]')

select jSON_MERGE('[4,5]','{"a":1}')

JSON_QUOTE(json_val) 将json_val用双引号括起来
select JSON_QUOTE('[4,5]')  #结果"[4,5]"

2、修改函数

/*1、json_set(),path中$就代表整个doc,然后可以用JavaScript的方式指定对象属性或者数组下标等.

执行效果,类似json的语法

$.a=456

$.b="bbb"

存在就修改,不存在就设置*/

update t set js=json_set('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb') where id=1

/*2、 JSON_ARRAY_APPEND 给指定的节点,添加元素,如果节点不是数组,则先转换成[doc]*/

-- JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)

-- 在指定path的json array尾部追加val。如果指定path是一个json object,则将其封装成一个json array再追加。

select JSON_ARRAY_APPEND('[1,2]','$','456')

select JSON_ARRAY_APPEND('[1,2]','$[0]','456')

select JSON_ARRAY_APPEND('[{"key":1},2]','$[0]','456')

/*3、JSON_ARRAY_INSERT 在数组的指定下标处插入元素,不会替换现有值*/

#数组的下标1处插入

SELECT JSON_ARRAY_INSERT('[1,2,3]','$[1]',4)

#在$[1]数组的下标1处插入

SELECT JSON_ARRAY_INSERT('[1,[1,2,3],3]','$[1][1]',4)

#若一个数组进行两次插入,则后续的插入是在前面插入的基础上的

SELECT JSON_ARRAY_INSERT('[1,2,3]','$[0]',4,'$[1]',5)

可以看成两次插入,第一次:SELECT JSON_ARRAY_INSERT('[1,2,3]','$[0]',4)

第二次:SELECT JSON_ARRAY_INSERT('[4,1,2,3]','$[1]',5)

/*4、JSON_SET 替换现有值并添加不存在的值*/

select json_set('{"a":456}','$[1]',123)

select JSON_SET('[1,2,3,4]','$[1]',123)

/*5、JSON_REPLACE 仅替换现有值*/

select JSON_REPLACE('[1,2,3,4]','$[1]',123)

#替换失败,因为数组没有第5个数

select JSON_REPLACE('[1,2,3,4]','$[4]',123)

3、查询函数

# json_keys返回键

select json_keys('{"a":1,"b":2}')

select json_keys('{"a":1,"b":{"c":30}}','$.b')

#数组没有key

select json_keys('{"a":1,"b":[1,2,3]}','$.b')

-- JSON_SEARCH 返回JSON文档中给定字符串的路径

-- JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])

-- 查询包含指定字符串的paths,并作为一个json array返回。如果有参数为NUL或path不存在,则返回NULL。

-- one_or_all:"one"表示查询到一个即返回;"all"表示查询所有。

-- search_str:要查询的字符串。 可以用LIKE里的'%'或‘_’匹配。

-- path:在指定path下查。

set @j = '["abc",[{"k":"10"},"def"],{"x":"abc"},{"y":"bcd"}]';

select JSON_SEARCH(@j,'one','abc');

select JSON_SEARCH(@j,'one','bcd');

select json_search('{"a":"abc","b":{"c":"dad"}}','one','%a%') #结果是$.a

select json_search('{"a":"abc","b":{"c":"dad"}}','all','%a%') #结果是["$.a", "$.b.c"]

select json_search('{"a":"abc","b":{"c":"dad"}}','all','%a%',null,'$.b') #指定了查询范围,只能在key为b的地方找,结果是"$.b.c"

select json_search('{"a":"abc","b":{"c":"dad"},"c":{"b":"aaa"}}','all','%a%',null,'$**.b') #$**.b意味着在每个节点下面,都找key为b的值,结果是["$.b.c", "$.c.b"]

#注意,只有json_extract和json_search中的path才支持通配,其他json_set,json_insert等都不支持。

/*JSON_EXTRACT(json_doc, path[, path] ...) 获得doc中某个或多个节点的值。*/

select json_extract('{"a":1,"b":2}','$.a')

#返回a对应的数组第2个元素

select json_extract('{"a":[1,2,3],"b":2}','$.a[1]')

#a.*通配a所有属性的值返回成数组。

select json_extract('{"a":{"a":1,"b":2,"c":3},"b":2}','$.a.*')

#通配$中所有层次下的属性b的值返回成数组。

select json_extract('{"a":{"a":1,"b":2,"c":3},"b":4}','$**.b')

 

select js,JSON_EXTRACT(js,"$[0]"),id from t where JSON_EXTRACT(js,"$[0]") = 123

# ->的作用类似于JSON_EXTRACT()获得节点中的值

select js,js->"$[0]",id from t where js->"$[0]" = 123

 

#JSON_UNQUOTE()  消除返回结果中的双引号

select JSON_UNQUOTE("str")

select JSON_EXTRACT('{"a":"吃饭、睡觉、打豆豆","b":2}','$.a')  #结果加双引号

select JSON_UNQUOTE(JSON_EXTRACT('{"a":"吃饭、睡觉、打豆豆","b":2}','$.a')) #结果不加双引号

 

#JSON_CONTAINS(json_doc, val[, path]) 指定path是否包含指定数据,包含返回1,否则返回0.如果有参数为NULL或path不存在,则返回null

select json_contains('{"a":1,"b":4}','{"a":1}')  #结果是1,包含

select json_contains('{"a":1,"b":4}','{"a":8}')  #结果是0,不包含

 

select json_contains('{"a":[1,2,3],"b":1}','[1,2]','$.a') #结果是1

 

select json_contains('{"a":[1,2,3],"b":1}','[1,2]')  #结果是0

select json_contains('{"a":[1,2,3],"b":1}','[1,2,3]') #结果是0

select json_contains('{"a":[1,2,3],"b":1}','{"a":[1,2,3]}') #结果是1

select json_contains('{"a":[1,2,3],"b":1}','{"a":[1,2]}') #结果是1

select json_contains('{"a":[1,2,3],"b":1}','{"a":[1,2,3,4]}') #结果是0

 

#JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)  检查是否存在指定路径,存在返回1,否则返回0.如果有参数为null,则返回null.

#类型 one只要有一个存在就为1,all全部存在才为1

select JSON_CONTAINS_PATH('{"a":1,"b":1}', 'one','$.a','$.c')  #结果是1

select JSON_CONTAINS_PATH('{"a":1,"b":1}', 'all','$.a','$.c')  #结果是0

select JSON_CONTAINS_PATH('{"a":1,"b":{"c":{"d":1}}}', 'one','$.b.c.d') #结果是1

select JSON_CONTAINS_PATH('{"a":1,"b":{"c":{"d":1}}}', 'one','$.a.c.d') #结果是0,a的下面没有c也没有d

 

#JSON_LENGTH(json_doc[, path]),返回数组的长度,如果是object则是属性个数,常量则为1

  • 标量的长度为1;
  • json array的长度为元素的个数;
  • json object的长度为key的个数。

select json_length('[1,2,3]')  #结果是3

select json_length('123')      #结果是1

select json_length('{"a":1,"b":2}') #结果是2

select json_length('{"a":1,"b":[1,2,3]}','$.b') #结果是3

 

#JSON_DEPTH(json_doc) 返回doc深度

#空的json array、json object或标量的深度为1

select json_depth('{}'),json_depth('[]'),json_depth('123') #结果1,1,1

select json_depth('[1,2,3,4,5,6]')                         #结果是2

select json_depth('{"a":{"b":{"c":1}}}')                   #结果是4

你可能感兴趣的:(sql,数据库,json,mysql)