zoukankan      html  css  js  c++  java
  • 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)
    
  • 相关阅读:
    OpenACC 书上的范例代码(Jacobi 迭代),part 4
    WRF 安装备忘
    荒川网格
    位运算骚操作 Part 3
    CUDA compiler driver nvcc 散点 part 2
    稀疏矩阵 part 5
    稀疏矩阵 part 4
    稀疏矩阵 part 3
    稀疏矩阵 part 2
    稀疏矩阵 part 1
  • 原文地址:https://www.cnblogs.com/wshenjin/p/10276678.html
Copyright © 2011-2022 走看看