mysql 5.7 json函数_MySQL5.7 JSON类型及其相关函数的学习

mysql> CREATE TABLE `json_table` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`info` json NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

mysql> select * from json_table ;

+----+------------------------------+

| id | info |

+----+------------------------------+

| 1 | {"age": 24, "name": "lucy"} |

| 2 | {"age": 20, "name": "lili"} |

| 3 | {"age": 25, "name": "curry"} |

+----+------------------------------+

3 rows in set (0.00 sec)

Creating JSON Values

MySQL里的json分为json array和json object。

JSON_TYPE():查看字段类型

JSON_ARRAY():返回json数组

JSON_OBJECT():返回json对象

JSON_MERGE():合并多个json文档

举个栗子:

#查看类型

mysql> select id, json_extract(info, '$.name') as name , json_type(json_extract(info, '$.name')) as type from json_table where id=3 ;

+----+---------+--------+

| id | name | type |

+----+---------+--------+

| 3 | "curry" | STRING |

+----+---------+--------+

1 row in set (0.00 sec)

#生成一个json数据组

mysql> select json_array('aaa', 'bbb', 'ddd') as array;

+-----------------------+

| array |

+-----------------------+

| ["aaa", "bbb", "ddd"] |

+-----------------------+

1 row in set (0.00 sec)

#生成一个json对象

mysql> select json_object('aaa', 1, 'bbb', 2, 'ddd', 3) as array;

+--------------------------------+

| array |

+--------------------------------+

| {"aaa": 1, "bbb": 2, "ddd": 3} |

+--------------------------------+

1 row in set (0.00 sec)

#将多个json文档合并

mysql> select json_merge(json_array('aaa', 'bbb', 'ddd'), json_object('aaa', 1, 'bbb', 2, 'ddd', 3)) as json ;

+-------------------------------------------------------+

| json |

+-------------------------------------------------------+

| ["aaa", "bbb", "ddd", {"aaa": 1, "bbb": 2, "ddd": 3}] |

+-------------------------------------------------------+

1 row in set, 1 warning (0.00 sec)

JSON查询

MySQL里的json分为json array和json object

对于json array,在索引数据时用从0开始的下标进行索引,$表示整个json对象,例如:$[0]、$[1]

对于json object,在索引数据时用key进行索引,含有特殊字符的key要用""括起来,比如$."my name")

提取json字段:json列->'$.键' 或 JSON_EXTRACT(json列 , '$.键')

去掉json字段双引号:JSON_UNQOUTE() 或者 json列->>'$.键'

提取JSON 字段的表达式可以用于SELECT查询列表 ,WHERE/HAVING , ORDER/GROUP BY语句中,JSON 中的元素搜索也是严格区分变量类型

json不同于字符串,不能当作字符串直接做比较,通过CAST()将字符串转换成JSON形式,再进行比较,后面举栗

举个栗子:

json列->'$.键' 查询:

mysql> select id, info->'$.name' as name from json_table ;

+----+---------+

| id | name |

+----+---------+

| 1 | "lucy" |

| 2 | "lili" |

| 3 | "curry" |

+----+---------+

3 rows in set (0.00 sec)

mysql> select id, info->'$.name' as name from json_table where info->'$.age' >=24;

+----+---------+

| id | name |

+----+---------+

| 1 | "lucy" |

| 3 | "curry" |

+----+---------+

2 rows in set (0.00 sec)

##复杂情况下的查询,例如

mysql> select info from json_table where id=3;

+----------------------------------------------------------------+

| info |

+----------------------------------------------------------------+

| ["abc", {"xxx": [123, 456], "my key": "my value"}, [666, 100]] |

+----------------------------------------------------------------+

1 row in set (0.00 sec)

## 查询json array的某个值

mysql> select info->'$[0]' from json_table where id=3 ;

+---------------+

| info->'$[0]' |

+---------------+

| "abc" |

+---------------+

1 row in set (0.00 sec)

## 查询json array中的的json object

mysql> select info->'$[1]."my key"' from json_table where id=3 ;

+--------------------------+

| info->'$[1]."my key"' |

+--------------------------+

| "my value" |

+--------------------------+

1 row in set (0.00 sec)

JSON_EXTRACT(json列 , '$.键')查询:

mysql> select id, json_extract(info, '$.name') as name from json_table ;

+----+---------+

| id | name |

+----+---------+

| 1 | "lucy" |

| 2 | "lili" |

| 3 | "curry" |

+----+---------+

3 rows in set (0.05 sec)

mysql> select id, json_extract(info, '$.name') as name from json_table where json_extract(info, '$.age') >= 24;

+----+---------+

| id | name |

+----+---------+

| 1 | "lucy" |

| 3 | "curry" |

+----+---------+

2 rows in set (0.00 sec)

JSON_UNQOUTE()方法举栗:

mysql> select id, json_unquote(json_extract(info, '$.name')) as name from json_table ;

+----+-------+

| id | name |

+----+-------+

| 1 | lucy |

| 2 | lili |

| 3 | curry |

+----+-------+

3 rows in set (0.00 sec)

mysql> select id, info->>'$.name' as name from json_table ;

+----+-------+

| id | name |

+----+-------+

| 1 | lucy |

| 2 | lili |

| 3 | curry |

+----+-------+

3 rows in set (0.00 sec)

JSON字段与字符串比较举栗:

mysql> select * from json_table where info = '{"age": 25, "name": "curry"}';

Empty set (0.00 sec)

mysql> select * from json_table where info = cast('{"age": 25, "name": "curry"}' as JSON);

+----+------------------------------+

| id | info |

+----+------------------------------+

| 3 | {"age": 25, "name": "curry"} |

+----+------------------------------+

1 row in set (0.00 sec)

JSON的索引

现在MySQL不支持对JSON列进行索引,官网文档的说明是:

JSON columns cannot be indexed. You can work around this restriction by creating an index on a generated column that extracts a scalar value from the JSON column.

虽然不支持直接在JSON列上建索引,但MySQL规定,可以首先使用路径表达式对JSON文档中的标量值建立虚拟列,然后在虚拟列上建立索引。这样用户可以使用表达式对自己感兴趣的键值建立索引。

栗如,创建索引:

mysql> alter table json_table add name varchar(20) generated always as (info->'$.name') virtual ;

Query OK, 0 rows affected (0.35 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> select * from json_table ;

+----+------------------------------+---------+

| id | info | name |

+----+------------------------------+---------+

| 1 | {"age": 24, "name": "lucy"} | "lucy" |

| 2 | {"age": 20, "name": "lili"} | "lili" |

| 3 | {"age": 25, "name": "curry"} | "curry" |

| 4 | {"age": 24, "name": "tom"} | "tom" |

| 5 | {"age": 24, "name": "jurry"} | "jurry" |

| 6 | {"age": 30, "name": "tmry"} | "tmry" |

+----+------------------------------+---------+

6 rows in set (0.00 sec)

mysql> select * from json_table where name=""tom"";

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'tom""' at line 1

mysql> select * from json_table where name="\"tom\"";

+----+----------------------------+-------+

| id | info | name |

+----+----------------------------+-------+

| 4 | {"age": 24, "name": "tom"} | "tom" |

+----+----------------------------+-------+

1 row in set (0.00 sec)

mysql> alter table json_table add index name_idx(name) ;

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table json_table \G

*************************** 1. row ***************************

Table: json_table

Create Table: CREATE TABLE `json_table` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`info` json NOT NULL,

`name` varchar(20) GENERATED ALWAYS AS (json_extract(`info`,'$.name')) VIRTUAL,

PRIMARY KEY (`id`),

KEY `name_idx` (`name`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

mysql> alter table json_table rename index name_idx to idx_name ;

Query OK, 0 rows affected (0.02 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table json_table \G

*************************** 1. row ***************************

Table: json_table

Create Table: CREATE TABLE `json_table` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`info` json NOT NULL,

`name` varchar(20) GENERATED ALWAYS AS (json_extract(`info`,'$.name')) VIRTUAL,

PRIMARY KEY (`id`),

KEY `idx_name` (`name`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

修改

JSON_INSERT() 插入新字段,对于已存在的字段无法修改

#插入新字段

mysql> update json_table set info=json_insert(info, '$.sex', 'M');

Query OK, 6 rows affected (0.30 sec)

Rows matched: 6 Changed: 6 Warnings: 0

mysql> select * from json_table ;

+----+-----------------------------------------------------------+

| id | info |

+----+-----------------------------------------------------------+

| 1 | {"age": 24, "sex": "M", "name": "lucy"} |

| 2 | {"age": 20, "sex": "M", "name": "lili"} |

| 3 | {"age": 25, "sex": "M", "name": "curry"} |

| 4 | {"age": 24, "sex": "M", "name": "tom"} |

| 5 | {"age": 24, "sex": "M", "name": "jurry"} |

| 6 | {"age": 30, "sex": "M", "name": "tmry"} |

+----+-----------------------------------------------------------+

6 rows in set (0.00 sec)

#对于已存在的字段无法修改

mysql> update json_table set info=json_insert(info, '$.name', 'LUCY') where id=1;

Query OK, 0 rows affected (0.00 sec)

Rows matched: 1 Changed: 0 Warnings: 0

mysql> select * from json_table where id=1 ;

+----+-----------------------------------------------------------+

| id | info |

+----+-----------------------------------------------------------+

| 1 | {"age": 24, "sex": "M", "name": "lucy"} |

+----+-----------------------------------------------------------+

6 rows in set (0.00 sec)

JSON_SET() 插入新值字段,并覆盖已经存在字段的值

#覆盖已经存在字段的值

mysql> update json_table set info=json_set(info, '$.name', 'LUCY') where id=1;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from json_table where id=1;

+----+-----------------------------------------------------------+

| id | info |

+----+-----------------------------------------------------------+

| 1 | {"age": 24, "sex": "M", "name": "LUCY"} |

+----+-----------------------------------------------------------+

1 row in set (0.00 sec)

#插入新值字段

mysql> update json_table set info=json_set(info, '$.class', 'python') where id=2;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from json_table where id=2;

+----+------------------------------------------------------------+

| id | info |

+----+------------------------------------------------------------+

| 2 | {"age": 20, "sex": "M", "name": "lili", "class": "python"} |

+----+------------------------------------------------------------+

1 row in set (0.00 sec)

JSON_REPLACE() 只替换存在的字段

mysql> update json_table set info=json_replace(info, '$.sex', 'W') where id=2;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from json_table where id = 2 ;

+----+------------------------------------------------------------+

| id | info |

+----+------------------------------------------------------------+

| 2 | {"age": 20, "sex": "W", "name": "lili", "class": "python"} |

+----+------------------------------------------------------------+

1 row in set (0.00 sec)

JSON_REMOVE() 删除 JSON 元素

mysql> update json_table set info=json_remove(info, '$.class') where id=2 ;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from json_table where id = 2 ;

+----+-----------------------------------------+

| id | info |

+----+-----------------------------------------+

| 2 | {"age": 20, "sex": "W", "name": "lili"} |

+----+-----------------------------------------+

1 row in set (0.00 sec)

你可能感兴趣的:(mysql,5.7,json函数)