您现在的位置:首页 >> 家居资讯

一文说透 MySQL JSON 变量!

发布时间:2025/11/01 12:17    来源:狮子山家居装修网

rt into t values('[1, "abc", null, true, "08:45:06.000000"]');

Query OK, 1 row affected (0.01 sec)

mysql> insert into t values('{"id": 87, "name": "carrot"}');

Query OK, 1 row affected (0.01 sec)

也可适用模板,都用的有 JSON_ARRAY() 和 JSON_OBJECT(),前者用做构造 JSON 为统计数据结构,后者用做构造 JSON 并不一定。如,

mysql> select json_array(1, "abc", null, true,curtime());

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

json_array(1, "abc", null, true,curtime()) |

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

[1, "abc", null, true, "10:12:25.000000"] |

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

1 row in set (0.01 sec)

mysql> select json_object('id', 87, 'name', 'carrot');

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

json_object('id', 87, 'name', 'carrot') |

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

{"id": 87, "name": "carrot"} |

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

1 row in set (0.00 sec)

对于 JSON XML,KEY 名不能重复使用。

如果弹出的绝对值中会存有重复使用 KEY,在 MySQL 8.0.3 早必先,遵循 first duplicate key wins 原则,都会存留第一个 KEY,末尾的将被丢弃干脆。

从 MySQL 8.0.3 开始,遵循的是 last duplicate key wins 原则,只都会存留终于一个 KEY。

解释器通过一个具体情况的解释器来先来两者的区别。

MySQL 5.7.36

mysql> select json_object('key1',10,'key2',20,'key1',30);

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

json_object('key1',10,'key2',20,'key1',30) |

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

{"key1": 10, "key2": 20} |

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

1 row in set (0.02 sec)

MySQL 8.0.27

mysql> select json_object('key1',10,'key2',20,'key1',30);

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

json_object('key1',10,'key2',20,'key1',30) |

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

{"key1": 30, "key2": 20} |

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

1 row in set (0.00 sec)

2、查看操纵

1)JSON_EXTRACT(json_doc, path[, path] ...)

其中会,json_doc 是 JSON XML,path 是切线。该模板都会从 JSON XML抽取登录切线(path)的表达模式。如果登录 path 不存有,都会回到 NULL。可登录多个 path,冗余到的多个绝对值都会以为统计数据结构表现形式回到。

解释器我们结合一些具体情况的解释器来先来 path 及 JSON_EXTRACT 的用词。

首必先我们先来为统计数据结构。

为统计数据结构的切线是通过斜线来指出的。第一个表达模式的斜线是 0。

mysql> select json_extract('[10, 20, [30, 40]]', '$[0]');

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

json_extract('[10, 20, [30, 40]]', '$[0]') |

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

10 |

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

1 row in set (0.00 sec)

mysql> select json_extract('[10, 20, [30, 40]]', '$[0]', '$[1]','$[2][0]');

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

json_extract('[10, 20, [30, 40]]', '$[0]', '$[1]','$[2][0]') |

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

[10, 20, 30] |

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

1 row in set (0.00 sec)

除此之外,还可通过 [M to N] 受益为统计数据结构的子集。

mysql> select json_extract('[10, 20, [30, 40]]', '$[0 to 1]');

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

json_extract('[10, 20, [30, 40]]', '$[0 to 1]') |

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

[10, 20] |

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

1 row in set (0.00 sec)

# 这里的 last 代表终于一个表达模式的斜线

mysql> select json_extract('[10, 20, [30, 40]]', '$[last-1 to last]');

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

json_extract('[10, 20, [30, 40]]', '$[last-1 to last]') |

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

[20, [30, 40]] |

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

1 row in set (0.00 sec)

也可通过 [*] 受益为统计数据结构中会的所有表达模式。

mysql> select json_extract('[10, 20, [30, 40]]', '$[*]');

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

json_extract('[10, 20, [30, 40]]', '$[*]') |

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

[10, 20, [30, 40]] |

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

1 row in set (0.00 sec)

接下来,我们先来并不一定。

并不一定的切线是通过 KEY 来指出的。

mysql> set @j='{"a": 1, "b": [2, 3], "a c": 4}';

Query OK, 0 rows affected (0.00 sec)

# 如果 KEY 在切线操纵符中会不政府所(譬如存有冒号),则在所述这个 KEY 时,必可作冒号同上出去。

mysql> select json_extract(@j, '$.a'), json_extract(@j, '$."a c"'), json_extract(@j, '$.b[1]');

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

json_extract(@j, '$.a') | json_extract(@j, '$."a c"') | json_extract(@j, '$.b[1]') |

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

1 | 4 | 3 |

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

1 row in set (0.00 sec)

除此之外,还可通过 .* 受益并不一定中会的所有表达模式。

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

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

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

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

[1, [2, 3], 4] |

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

1 row in set (0.00 sec)

# 这里的 $**.b 冗余 $.a.b 和 $.c.b

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

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

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

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

[1, 2] |

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

1 row in set (0.00 sec)

2)column->path

column->path,包同上末尾说道的 column->>path,都是语言糖,在实际适用的时候都都会产物为 JSON_EXTRACT。

column->path 比如说 JSON_EXTRACT(column, path) ,只能登录一个path。

create table t(c2 json);

insert into t values('{"empno": 1001, "ename": "jack"}'), ('{"empno": 1002, "ename": "mark"}');

mysql> select c2, c2->"$.ename" from t;

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

c2 | c2->"$.ename" |

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

{"empno": 1001, "ename": "jack"} | "jack" |

{"empno": 1002, "ename": "mark"} | "mark" |

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

2 rows in set (0.00 sec)

mysql> select * from t where c2->"$.empno" = 1001;

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

c1 | c2 |

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

1 | {"empno": 1001, "ename": "jack"} |

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

1 row in set (0.00 sec)

3)column->>path

同 column->path 类似,无论如何其回到的是字节。表列出三者是映射的。

JSON_UNQUOTE( JSON_EXTRACT(column, path) ) JSON_UNQUOTE(column -> path) column->>path

mysql> select c2->'$.ename',json_extract(c2, "$.ename"),json_unquote(c2->'$.ename'),c2->>'$.ename' from t;

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

c2->'$.ename' | json_extract(c2, "$.ename") | json_unquote(c2->'$.ename') | c2->>'$.ename' |

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

"jack" | "jack" | jack | jack |

"mark" | "mark" | mark | mark |

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

2 rows in set (0.00 sec)

3、简化操纵

1)JSON_INSERT(json_doc, path, val[, path, val] ...)

弹出新绝对值。

仅当登录方位或登录 KEY 的绝对值不存有时,才分派弹出操纵。另外,如果登录的 path 是为统计数据结构斜线,且 json_doc 不是为统计数据结构,该模板首必先都会将 json_doc 产物为为统计数据结构,然后先弹出新绝对值。

解释器我们看几个解释器。

mysql> select json_insert('1','$[0]',"10");

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

json_insert('1','$[0]',"10") |

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

1 |

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

1 row in set (0.00 sec)

mysql> select json_insert('1','$[1]',"10");

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

json_insert('1','$[1]',"10") |

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

[1, "10"] |

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

1 row in set (0.01 sec)

mysql> select json_insert('["1","2"]','$[2]',"10");

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

json_insert('["1","2"]','$[2]',"10") |

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

["1", "2", "10"] |

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

1 row in set (0.00 sec)

mysql> set @j = '{ "a": 1, "b": [2, 3]}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_insert(@j, '$.a', 10, '$.c', '[true, false]');

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

json_insert(@j, '$.a', 10, '$.c', '[true, false]') |

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

{"a": 1, "b": [2, 3], "c": "[true, false]"} |

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

1 row in set (0.00 sec)

2)JSON_SET(json_doc, path, val[, path, val] ...)

弹出新绝对值,并替换之前存有的绝对值。

换言之,如果登录方位或登录 KEY 的绝对值不存有,都会分派弹出操纵,如果存有,则分派新增操纵。

mysql> set @j = '{ "a": 1, "b": [2, 3]}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_set(@j, '$.a', 10, '$.c', '[true, false]');

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

json_set(@j, '$.a', 10, '$.c', '[true, false]') |

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

{"a": 10, "b": [2, 3], "c": "[true, false]"} |

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

1 row in set (0.00 sec)

3)JSON_REPLACE(json_doc, path, val[, path, val] ...)

替换之前存有的绝对值。

mysql> set @j = '{ "a": 1, "b": [2, 3]}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_replace(@j, '$.a', 10, '$.c', '[true, false]');

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

json_replace(@j, '$.a', 10, '$.c', '[true, false]') |

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

{"a": 10, "b": [2, 3]} |

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

1 row in set (0.00 sec)

4、删掉操纵

JSON_REMOVE(json_doc, path[, path] ...)

删掉 JSON XML登录方位的表达模式。

mysql> set @j = '{ "a": 1, "b": [2, 3]}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_remove(@j, '$.a');

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

JSON_REMOVE(@j, '$.a') |

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

{"b": [2, 3]} |

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

1 row in set (0.00 sec)

mysql> set @j = '["a", ["b", "c"], "d", "e"]';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_remove(@j, '$[1]');

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

JSON_REMOVE(@j, '$[1]') |

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

["a", "d", "e"] |

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

1 row in set (0.00 sec)

mysql> select json_remove(@j, '$[1]','$[2]');

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

JSON_REMOVE(@j, '$[1]','$[2]') |

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

["a", "d"] |

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

1 row in set (0.00 sec)

mysql> select json_remove(@j, '$[1]','$[1]');

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

JSON_REMOVE(@j, '$[1]','$[1]') |

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

["a", "e"] |

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

1 row in set (0.00 sec)

终于一个查看,虽然两个 path 都是 '$[1]' ,但依赖性并不一定不一样,第一个 path 的依赖性并不一定是 '["a", ["b", "c"], "d", "e"]' ,第二个 path 的依赖性并不一定是删掉了 '$[1]' 后的为统计数据结构,即 '["a", "d", "e"]' 。

三、如何对 JSON 文件名创建者为统计数据库

同 TEXT,BLOB 文件名一样,JSON 文件名不并不必需要单独创建者为统计数据库。

mysql> create table t(c1 json, index (c1));

ERROR 3152 (42000): JSON column 'c1' supports indexing only via generated columns on a specified JSON path.

即使默许,实际上也太大,因为我们一般是基于XML中会的表达模式完形同查看,仅仅都会基于整个 JSON XML。

对XML中会的表达模式完形同查看,就并不必需要比如说 MySQL 5.7 带入的ID四支及模板为统计数据库。

解释器我们来看一个具体情况的解释器。

# C2 即ID四支

# index (c2) 对ID四支移除为统计数据库。

create table t ( c1 json, c2 varchar(10) as (JSON_UNQUOTE(c1 -> "$.name")), index (c2) );

insert into t (c1) values ('{"id": 1, "name": "a"}'), ('{"id": 2, "name": "b"}'), ('{"id": 3, "name": "c"}'), ('{"id": 4, "name": "d"}');

mysql> explain select * from t where c2 = 'a';

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

id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

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

1 | SIMPLE | t | NULL | ref | c2 | c2 | 43 | const | 1 | 100.00 | NULL |

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

1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t where c1->'$.name' = 'a';

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

id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

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

1 | SIMPLE | t | NULL | ref | c2 | c2 | 43 | const | 1 | 100.00 | NULL |

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

1 row in set, 1 warning (0.00 sec)

可以看到,无论是适用ID四支,还是XML中会的表达模式来查看,都可以依靠上为统计数据库。

提醒,在创建者ID四支时必需登录 JSON_UNQUOTE,将 c1 -> "$.name" 的回到绝对值匹配为字节。

四、如何将存储器 JSON 字节的字节文件名换装为 JSON 文件名

在 MySQL 默许 JSON 各种类型早必先,对于 JSON XML,一般是以字节的表现形式存储器在字节各种类型(VARCHAR 或 TEXT)中会。

在 JSON 各种类型出来之后,如何将这些字节文件名换装为 JSON 文件名呢?

为易于演示,这里首必先构建的测试为统计数据。

create table t (id int auto_increment primary key, c1 text);

insert into t (c1) values ('{"id": "1", "name": "a"}'), ('{"id": "2", "name": "b"}'), ('{"id": "3", "name": "c"}'), ('{"id", "name": "d"}');

提醒,终于一个XML有问题,不是合格者的 JSON XML。

如果适用 DDL 单独简化文件名的模板,都会报错。

mysql> alter table t modify c1 json;

ERROR 3140 (22032): Invalid JSON text: "Missing a colon after a name of object member." at position 5 in value for column '#sql-7e1c_1f6.c1'.

解释器,我们先来具体情况的换装步骤。

1)适用 json_valid 模板找出不充分依靠 JSON 文档决定的XML。

mysql> select * from t where json_valid(c1) = 0;

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

id | c1 |

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

4 | {"id", "name": "d"} |

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

1 row in set (0.00 sec)

2)处理事件不充分依靠 JSON 文档决定的XML。

mysql> update t set c1='{"id": "4", "name": "d"}' where id=4;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

3)将 TEXT 文件名简化为 JSON 文件名。

mysql> select * from t where json_valid(c1) = 0;

Empty set (0.00 sec)

mysql> alter table t modify c1 json;

Query OK, 4 rows affected (0.13 sec)

Records: 4 Duplicates: 0 Warnings: 0

五、适用 JSON 时的提醒事项

对于 JSON 各种类型,有表列出几点并不必需要提醒:

1)在 MySQL 8.0.13 早必先,不并不必需要对 BLOB,TEXT,GEOMETRY,JSON 文件名设预设绝对值。从 MySQL 8.0.13 开始,终止了这个受限制。

设时,提醒预设绝对值必需通过小同上号()同上出去,否则的话,还是都会提示 JSON 文件名不并不必需要设预设绝对值。

mysql> create table t(c1 json not null default (''));

Query OK, 0 rows affected (0.03 sec)

mysql> create table t(c1 json not null default '');

ERROR 1101 (42000): BLOB, TEXT, GEOMETRY or JSON column 'c1' can't have a default value

2)不并不必需要单独创建者为统计数据库,可创建者模板为统计数据库。

3)JSON 四支的较大大小不一和 LONGBLOB(LONGTEXT)一样,都是 4G。

4)弹出时,单个XML的大小不一受到 max_allowed_packet 的受限制,该模板较大是 1G。

六、Partial Updates

在 MySQL 5.7 中会,对 JSON XML完形同新增,其处理事件策略是,删掉旧的XML,先弹出新的XML。即使这个简化很表面,只涉及几个字节,也都会替换干脆整个XML。很显然,这种处理事件模式的可靠性较为偏颇高。

在 MySQL 8.0 中会,针对 JSON XML,带入了一项新的适应性-Partial Updates(外新增),默许 JSON XML的原来新增。归功于这个适应性,JSON XML的处理事件效能想得到了不小提升。

解释器我们具体情况来先来。

1、适用 Partial Updates 的有条件

为易于阐述,这里必先构造的测试为统计数据。

create table t (id int auto_increment primary key, c1 json);

insert into t (c1) values ('{"id": 1, "name": "a"}'), ('{"id": 2, "name": "b"}'), ('{"id": 3, "name": "c"}'), ('{"id": 4, "name": "d"}');

mysql> select * from t;

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

id | c1 |

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

1 | {"id": 1, "name": "a"} |

2 | {"id": 2, "name": "b"} |

3 | {"id": 3, "name": "c"} |

4 | {"id": 4, "name": "d"} |

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

4 rows in set (0.00 sec)

适用 Partial Updates 必需充分依靠表列出有条件:

1)被新增的四支是 JSON 各种类型。

2)适用 JSON_SET,JSON_REPLACE,JSON_REMOVE 完形同 UPDATE 操纵,如,

update t set c1=json_remove(c1,'$.id') where id=1;

不适用这三个模板,而显式赋绝对值,就不都会完形同外新增,如,

update t set c1='{"id": 1, "name": "a"}' where id=1;

3)转换成四支和目标四支必须是同一四支,如,

update t set c1=json_replace(c1,'$.id',10) where id=1;

否则的话,就不都会完形同外新增,如,

update t set c1=json_replace(c2,'$.id',10) where id=1;

4)更加改前后,JSON XML的自由空间适用不都会增颇高。

关于终于一个有条件,我们先来解释器这个解释器。

mysql> select *,json_storage_size(c1),json_storage_free(c1) from t where id=1;

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

id | c1 | json_storage_size(c1) | json_storage_free(c1) |

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

1 | {"id": 1, "name": "a"} | 27 | 0 |

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

1 row in set (0.00 sec)

mysql> update t set c1=json_remove(c1,'$.id') where id=1;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select *,json_storage_size(c1),json_storage_free(c1) from t where id=1;

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

id | c1 | json_storage_size(c1) | json_storage_free(c1) |

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

1 | {"name": "a"} | 27 | 9 |

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

1 row in set (0.00 sec)

mysql> update t set c1=json_set(c1,'$.id',3306) where id=1;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select *,json_storage_size(c1),json_storage_free(c1) from t where id=1;

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

id | c1 | json_storage_size(c1) | json_storage_free(c1) |

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

1 | {"id": 3306, "name": "a"} | 27 | 0 |

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

1 row in set (0.00 sec)

mysql> update t set c1=json_set(c1,'$.id','mysql') where id=1;

Query OK, 1 row affected (0.01 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select *,json_storage_size(c1),json_storage_free(c1) from t where id=1;

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

id | c1 | json_storage_size(c1) | json_storage_free(c1) |

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

1 | {"id": "mysql", "name": "a"} | 33 | 0 |

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

1 row in set (0.00 sec)

解释器中会,比如说了两个模板:JSON_STORAGE_SIZE 和 JSON_STORAGE_FREE ,前者用来受益 JSON XML的自由空间适用持续性,后者用来受益 JSON XML在分派原来新增后的自由空间拘押持续性。

这里多达分派了三次 UPDATE 操纵,前两次是原来新增,第三次不是。同样是 JSON_SET 操纵,为什么第一次是原来新增,而第二次不是呢?

因为第一次的 JSON_SET 复用了 JSON_REMOVE 拘押的自由空间。而第二次的 JSON_SET 分派的是新增操纵,且 'mysql' 比 3306 并不必需要更加多的存储器自由空间。

2、如何在 binlog 中会打开 Partial Updates

Partial Updates 也许适用做存储器变速箱层,还可用做主从复制布景。

主从复制打开 Partial Updates,只必需将模板 binlog_row_value_options(预设为空)设为 PARTIAL_JSON。

解释器具体情况来先来,同一个 UPDATE 操纵,打开和不打开 Partial Updates,在 binlog 中会的记事有何区别。

update t set c1=json_replace(c1,'$.id',10) where id=1;

不打开

### UPDATE MLT-slowtechMLT-.MLT-tMLT-

### WHERE

### @1=1

### @2='{"id": "1", "name": "a"}'

### SET

### @1=1

### @2='{"id": 10, "name": "a"}'

打开

### UPDATE MLT-slowtechMLT-.MLT-tMLT-

### WHERE

### @1=1

### @2='{"id": 1, "name": "a"}'

### SET

### @1=1

### @2=JSON_REPLACE(@2, '$.id', 10)

对比 binlog 的内容,可以看到,不打开,无论是简化前的复制(before_image)还是简化后的复制(after_image),记事的都是完备XML。而打开后,对于简化后的复制,记事的是命令,而不是完备XML,这样可更加少仅有一半的自由空间。

在将 binlog_row_value_options 设为 PARTIAL_JSON 后,对于可适用 Partial Updates 的操纵,在 binlog 中会,取而代之通过 ROWS_EVENT 来记事,而是新增了一个 PARTIAL_UPDATE_ROWS_EVENT 的事件各种类型。

并不必需要提醒的是,binlog 中会适用 Partial Updates,只必需充分依靠存储器变速箱层适用 Partial Updates 的前三个有条件,无须考虑更加改前后,JSON XML的自由空间适用应该都会增颇高。

3、关于 Partial Updates 的效能的测试

首必先构造的测试为统计数据,t 表多达有 16 个XML,每个XML仅有 10 MB。

create table t(id int auto_increment primary key,

json_col json,

name varchar(100) as (json_col->>'$.name'),

age int as (json_col->'$.age'));

insert into t(json_col) values

(json_object('name', 'Joe', 'age', 24,

'data', repeat('x', 10 * 1000 * 1000))),

(json_object('name', 'Sue', 'age', 32,

'data', repeat('y', 10 * 1000 * 1000))),

(json_object('name', 'Pete', 'age', 40,

'data', repeat('z', 10 * 1000 * 1000))),

(json_object('name', 'Jenny', 'age', 27,

'data', repeat('w', 10 * 1000 * 1000)));

insert into t(json_col) select json_col from t;

insert into t(json_col) select json_col from t;

接下来,的测试下述 SQL

update t set json_col = json_set(json_col, '$.age', age + 1);

在表列出四种布景下的分派星期:

MySQL 5.7.36 MySQL 8.0.27 MySQL 8.0.27,binlog_row_value_options=PARTIAL_JSON MySQL 8.0.27,binlog_row_value_options=PARTIAL_JSON + binlog_row_image=MINIMAL

分别分派 10 次,去干脆较大绝对值和最小绝对值后求平均绝对值。

终于的的测试结果如下:

以 MySQL 5.7.36 的查看星期作为标准:

MySQL 8.0 只打开存储器变速箱层的 Partial Updates,查看星期比 MySQL 5.7 较慢 1.94 倍。 MySQL 8.0 同时打开存储器变速箱层和 binlog 中会的 Partial Updates,查看星期比 MySQL 5.7 较慢 4.87 倍。 如果在 2 的改进,同时将 binlog_row_image 设为 MINIMAL,查看星期更加是比 MySQL 5.7 较慢 102.22 倍。

当然,在生产线状况,我们一般仅仅将 binlog_row_image 设为 MINIMAL。

但即便如此,只打开存储器变速箱层和 binlog 中会的 Partial Updates,查看星期也比 MySQL 5.7 较慢 4.87 倍,效能提升还是相当显着的。

七、其它 JSON 模板

1、查看具体情况

1)JSON_CONTAINS(target, candidate[, path])

判别 target XML应该包涵 candidate XML,如果包涵,则回到 1,否则是 0。

mysql> set @j = '{"a": [1, 2], "b": 3, "c": {"d": 4}}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_contains(@j, '1', '$.a'),json_contains(@j, '1', '$.b');

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

json_contains(@j, '1', '$.a') | json_contains(@j, '1', '$.b') |

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

1 | 0 |

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

1 row in set (0.00 sec)

mysql> select json_contains(@j,'{"d": 4}','$.a'),json_contains(@j,'{"d": 4}','$.c');

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

json_contains(@j,'{"d": 4}','$.a') | json_contains(@j,'{"d": 4}','$.c') |

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

0 | 1 |

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

1 row in set (0.00 sec)

2)JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)

判别登录的 path 应该存有,存有,则回到 1,否则是 0。

模板中会的 one_or_all 可登录 one 或 all,one 是随意一个切线存有就回到 1,all 是所有切线都存有才回到 1。

mysql> set @j = '{"a": [1, 2], "b": 3, "c": {"d": 4}}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_contains_path(@j, 'one', '$.a', '$.e'), json_contains_path(@j, 'all', '$.a', '$.e');

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

json_contains_path(@j, 'one', '$.a', '$.e') | json_contains_path(@j, 'all', '$.a', '$.e') |

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

1 | 0 |

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

1 row in set (0.00 sec)

mysql> select json_contains_path(@j, 'one', '$.c.d'),json_contains_path(@j, 'one', '$.a.d');

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

json_contains_path(@j, 'one', '$.c.d') | json_contains_path(@j, 'one', '$.a.d') |

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

1 | 0 |

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

1 row in set (0.00 sec)

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

回到某个字节(search_str)在 JSON XML中会的方位,其中会,

one_or_all:冗余的次为数,one 是只冗余一次,all 是冗余所有。如果冗余到多个,结果都会以为统计数据结构的表现形式回到。 search_str:字节串,默许模糊冗余:% 和 _ 。 escape_char:短语符,如果该模板不筑成或为 NULL,则取预设短语符。 path:索引切线。

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

Query OK, 0 rows affected (0.00 sec)

mysql> select json_search(@j, 'one', 'abc'),json_search(@j, 'all', 'abc'),json_search(@j, 'all', 'ghi');

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

json_search(@j, 'one', 'abc') | json_search(@j, 'all', 'abc') | json_search(@j, 'all', 'ghi') |

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

"$[0]" | ["$[0]", "$[2].x"] | NULL |

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

1 row in set (0.00 sec)

mysql> select json_search(@j, 'all', '%b%', NULL, '$[1]'), json_search(@j, 'all', '%b%', NULL, '$[3]');

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

json_search(@j, 'all', '%b%', NULL, '$[1]') | json_search(@j, 'all', '%b%', NULL, '$[3]') |

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

NULL | "$[3].y" |

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

1 row in set (0.00 sec)

4)JSON_KEYS(json_doc[, path])

回到 JSON XML最外层的 key,如果登录了 path,则回到该 path 相异表达模式最外层的 key。

mysql> select json_keys('{"a": 1, "b": {"c": 30}}');

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

json_keys('{"a": 1, "b": {"c": 30}}') |

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

["a", "b"] |

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

1 row in set (0.00 sec)

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

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

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

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

["c"] |

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

1 row in set (0.00 sec)

5)JSON_VALUE(json_doc, path)

8.0.21 带入的,从 JSON XML抽取登录切线(path)的表达模式。

该模板的完备语言如下:

JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error])

on_empty:

{NULL | ERROR | DEFAULT value} ON EMPTY

on_error:

{NULL | ERROR | DEFAULT value} ON ERROR

其中会:

RETURNING type:回到绝对值的各种类型,不登录,则预设是 VARCHAR(512)。不登录简体中文,则预设是 utf8mb4,且区隔大小不一写。 on_empty:如果登录切线无法绝对值,都会触发 on_empty 主语, 预设是回到 NULL,也可登录 ERROR 抛出误判,或者通过 DEFAULT value 回到预设绝对值。 on_error:三种持续性下都会触发 on_error 主语:从为统计数据结构或并不一定中会抽取表达模式时,都会解析到多个绝对值;各种类型匹配误判,譬如将 "abc" 匹配为 unsigned 各种类型;绝对值被 truncate 了。预设是回到 NULL。

mysql> select json_value('{"item": "shoes", "price": "49.95"}', '$.item');

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

json_value('{"item": "shoes", "price": "49.95"}', '$.item') |

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

shoes |

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

1 row in set (0.00 sec)

mysql> select json_value('{"item": "shoes", "price": "49.95"}', '$.price' returning decimal(4,2)) as price;

+-------+

price |

+-------+

49.95 |

+-------+

1 row in set (0.00 sec)

mysql> select json_value('{"item": "shoes", "price": "49.95"}', '$.price1' error on empty);

ERROR 3966 (22035): No value was found by 'json_value' on the specified path.

mysql> select json_value('[1, 2, 3]', '$[1 to 2]' error on error);

ERROR 3967 (22034): More than one value was found by 'json_value' on the specified path.

mysql> select json_value('{"item": "shoes", "price": "49.95"}', '$.item' returning unsigned error on error) as price;

ERROR 1690 (22003): UNSIGNED value is out of range in 'json_value'

6)value MEMBER OF(json_array)

判别 value 到底 JSON 为统计数据结构的一个表达模式,如果是,则回到 1,否则是 0。

mysql> select 17 member of('[23, "abc", 17, "ab", 10]');

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

17 member of('[23, "abc", 17, "ab", 10]') |

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

1 |

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

1 row in set (0.00 sec)

mysql> select cast('[4,5]' as json) member of('[[3,4],[4,5]]');

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

cast('[4,5]' as json) member of('[[3,4],[4,5]]') |

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

1 |

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

1 row in set (0.00 sec)

7)JSON_OVERLAPS(json_doc1, json_doc2)

MySQL 8.0.17 带入的,用来相当两个 JSON XML应该有相异的键绝对值对或为统计数据结构表达模式,如果有,则回到 1,否则是 0。如果两个模板都是乘积,则判别这两个乘积应该相等。

mysql> select json_overlaps('[1,3,5,7]', '[2,5,7]'),json_overlaps('[1,3,5,7]', '[2,6,8]');

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

json_overlaps('[1,3,5,7]', '[2,5,7]') | json_overlaps('[1,3,5,7]', '[2,6,8]') |

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

1 | 0 |

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

1 row in set (0.00 sec)

mysql> select json_overlaps('{"a":1,"b":2}', '{"c":3,"d":4,"b":2}');

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

json_overlaps('{"a":1,"b":2}', '{"c":3,"d":4,"b":2}') |

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

1 |

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

1 row in set (0.00 sec)

mysql> select json_overlaps('{"a":1,"b":2}', '{"c":3,"d":4,"b":10}');

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

json_overlaps('{"a":1,"b":2}', '{"c":3,"d":4,"b":10}') |

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

0 |

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

1 row in set (0.00 sec)

mysql> select json_overlaps('5', '5'),json_overlaps('5', '6');

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

json_overlaps('5', '5') | json_overlaps('5', '6') |

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

1 | 0 |

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

1 row in set (0.00 sec)

从 MySQL 8.0.17 开始,InnoDB 默许多绝对值为统计数据库,可用在 JSON 为统计数据结构中会。当我们适用 JSON_CONTAINS、MEMBER OF、JSON_OVERLAPS 完形同为统计数据结构具体情况的操纵时,可适用多绝对值为统计数据库来加较慢查看。

2、简化具体情况

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

向为统计数据结构登录方位追加表达模式。如果登录 path 不存有,则不移除。

mysql> set @j = '["a", ["b", "c"], "d"]';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_array_append(@j, '$[0]', 1, '$[1][0]', 2, '$[3]', 3);

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

json_array_append(@j, '$[0]', 1, '$[1][0]', 2, '$[3]', 3) |

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

[["a", 1], [["b", 2], "c"], "d"] |

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

1 row in set (0.00 sec)

mysql> set @j = '{"a": 1, "b": [2, 3], "c": 4}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_array_append(@j, '$.b', 'x', '$', 'z');

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

json_array_append(@j, '$.b', 'x', '$', 'z') |

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

[{"a": 1, "b": [2, 3, "x"], "c": 4}, "z"] |

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

1 row in set (0.00 sec)

2)JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)

向为统计数据结构登录方位弹出表达模式。

mysql> set @j = '["a", ["b", "c"],{"d":"e"}]';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_array_insert(@j, '$[0]', 1);

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

json_array_insert(@j, '$[0]', 1) |

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

[1, "a", ["b", "c"], {"d": "e"}] |

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

1 row in set (0.00 sec)

mysql> select json_array_insert(@j, '$[1]', cast('[1,2]' as json));

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

json_array_insert(@j, '$[1]', cast('[1,2]' as json)) |

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

["a", [1, 2], ["b", "c"], {"d": "e"}] |

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

1 row in set (0.00 sec)

mysql> select json_array_insert(@j, '$[5]', 2);

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

json_array_insert(@j, '$[5]', 2) |

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

["a", ["b", "c"], {"d": "e"}, 2] |

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

1 row in set (0.00 sec)

3)JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)

MySQL 8.0.3 带入的,用来新设多个 JSON XML。其新设原则上如下:

如果两个XML不全是 JSON 并不一定,则新设后的结果是第二个XML。 如果两个XML都是 JSON 并不一定,且不存有着为名 KEY,则新设后的XML包同上两个XML的所有表达模式,如果存有着为名 KEY,则第二个XML的绝对值都会覆盖第一个。

mysql> select json_merge_patch('[1, 2]', '[3, 4]'), json_merge_patch('[1, 2]', '{"a": 123}');

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

json_merge_patch('[1, 2]', '[3, 4]') | json_merge_patch('[1, 2]', '{"a": 123}') |

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

[3, 4] | {"a": 123} |

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

1 row in set (0.00 sec)

mysql> select json_merge_patch('{"a": 1}', '{"b": 2}'),json_merge_patch('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }');

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

json_merge_patch('{"a": 1}', '{"b": 2}') | json_merge_patch('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }') |

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

{"a": 1, "b": 2} | {"a": 3, "b": 2, "c": 4} |

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

1 row in set (0.00 sec)

# 如果第二个XML存有 null 绝对值,XML新设后不都会控制器相异的 KEY。

mysql> select json_merge_patch('{"a":1, "b":2}', '{"a":3, "b":null}');

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

json_merge_patch('{"a":1, "b":2}', '{"a":3, "b":null}') |

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

{"a": 3} |

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

1 row in set (0.00 sec)

4)JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)

MySQL 8.0.3 带入的,用来代替 JSON_MERGE。也是用来新设XML,但新设原则上与 JSON_MERGE_PATCH 不尽相同。

两个XML中会,只要有一个XML是为统计数据结构,则另外一个XML都会新设到该为统计数据结构中会。 两个XML都是 JSON 并不一定,若存有着为名 KEY ,第二个XML并不都会覆盖第一个,而是都会将绝对值 append 到第一个XML中会。

mysql> select json_merge_preserve('1','2'),json_merge_preserve('[1, 2]', '[3, 4]');

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

json_merge_preserve('1','2') | json_merge_preserve('[1, 2]', '[3, 4]') |

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

[1, 2] | [1, 2, 3, 4] |

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

1 row in set (0.00 sec)

mysql> select json_merge_preserve('[1, 2]', '{"a": 123}'), json_merge_preserve('{"a": 123}', '[3,4]');

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

json_merge_preserve('[1, 2]', '{"a": 123}') | json_merge_preserve('{"a": 123}', '[3,4]') |

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

[1, 2, {"a": 123}] | [{"a": 123}, 3, 4] |

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

1 row in set (0.00 sec)

mysql> select json_merge_preserve('{"a": 1}', '{"b": 2}'), json_merge_preserve('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }');

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

json_merge_preserve('{"a": 1}', '{"b": 2}') | json_merge_preserve('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }') |

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

{"a": 1, "b": 2} | {"a": [1, 3], "b": 2, "c": 4} |

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

1 row in set (0.00 sec)

5)JSON_MERGE(json_doc, json_doc[, json_doc] ...)

与 JSON_MERGE_PRESERVE 依赖性一样,从 MySQL 8.0.3 开始不指出同意适用,必先前都会移除。

3、其它特别设计模板

1)JSON_QUOTE(string)

生形同必必需的 JSON 字节,主要是对一些特殊字节(如冒号)完形同短语。

mysql> select json_quote('null'), json_quote('"null"'), json_quote('[1, 2, 3]');

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

json_quote('null') | json_quote('"null"') | json_quote('[1, 2, 3]') |

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

"null" | ""null"" | "[1, 2, 3]" |

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

1 row in set (0.00 sec)

除此之外,也可通过 CAST(value AS JSON) 完形同各种类型匹配。

2)JSON_UNQUOTE(json_val)

将 JSON 短语形同字节控制器。

mysql> select c2->'$.ename',json_unquote(c2->'$.ename'),

-> json_valid(c2->'$.ename'),json_valid(json_unquote(c2->'$.ename')) from t;

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

c2->'$.ename' | json_unquote(c2->'$.ename') | json_valid(c2->'$.ename') | json_valid(json_unquote(c2->'$.ename')) |

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

"jack" | jack | 1 | 0 |

"mark" | mark | 1 | 0 |

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

2 rows in set (0.00 sec)

抽象地看,没加 JSON_UNQUOTE 字节都会用冒号引出去,加了 JSON_UNQUOTE 就无法。但直觉上,前者是 JSON 中会的 STRING 各种类型,后者是 MySQL 中会的字节各种类型,这一点可通过 JSON_VALID 来判别。

3)JSON_OBJECTAGG(key, value)

取表中会的两四支作为模板,其中会,第一四支是 key,第二四支是 value,回到 JSON 并不一定。如,

mysql> select * from emp;

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

deptno | ename | sal |

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

10 | emp_1001 | 100.00 |

10 | emp_1002 | 200.00 |

20 | emp_1003 | 300.00 |

20 | emp_1004 | 400.00 |

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

4 rows in set (0.00 sec)

mysql> select json_objectagg(ename,sal) from emp;

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

json_objectagg(ename,sal) |

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

{"emp_1001": 100.00, "emp_1002": 200.00, "emp_1003": 300.00, "emp_1004": 400.00} |

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

1 row in set (0.00 sec)

mysql> select deptno,json_objectagg(ename,sal) from emp group by deptno;

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

deptno | json_objectagg(ename,sal) |

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

10 | {"emp_1001": 100.00, "emp_1002": 200.00} |

20 | {"emp_1003": 300.00, "emp_1004": 400.00} |

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

2 rows in set (0.00 sec)

4)JSON_ARRAYAGG(col_or_expr)

将四支的绝对值交联形同 JSON 为统计数据结构,提醒,JSON 为统计数据结构中会表达模式的依序是随机的。

mysql> select json_arrayagg(ename) from emp;

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

json_arrayagg(ename) |

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

["emp_1001", "emp_1002", "emp_1003", "emp_1004"] |

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

1 row in set (0.00 sec)

mysql> select deptno,json_arrayagg(ename) from emp group by deptno;

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

deptno | json_arrayagg(ename) |

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

10 | ["emp_1001", "emp_1002"] |

20 | ["emp_1003", "emp_1004"] |

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

2 rows in set (0.00 sec)

5)JSON_PRETTY(json_val)

将 JSON 文档化控制器。

mysql> select json_pretty("[1,3,5]");

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

json_pretty("[1,3,5]") |

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

[

1,

3,

5

] |

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

1 row in set (0.00 sec)

mysql> select json_pretty('{"a":"10","b":"15","x":"25"}');

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

json_pretty('{"a":"10","b":"15","x":"25"}') |

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

{

"a": "10",

"b": "15",

"x": "25"

} |

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

1 row in set (0.00 sec)

6)JSON_STORAGE_FREE(json_val)

MySQL 8.0 新增的,与 Partial Updates 有关,用做计数 JSON XML在完形同外新增后的剩余自由空间。

7)JSON_STORAGE_SIZE(json_val)

MySQL 5.7.22 带入的,用做计数 JSON XML的自由空间适用持续性。

8)JSON_DEPTH(json_doc)

回到 JSON XML的较大浅层。对于空为统计数据结构,空并不一定,乘积绝对值,其浅层为 1。

mysql> select json_depth('{}'),json_depth('[10, 20]'),json_depth('[10, {"a": 20}]');

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

json_depth('{}') | json_depth('[10, 20]') | json_depth('[10, {"a": 20}]') |

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

1 | 2 | 3 |

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

1 row in set (0.00 sec)

9)JSON_LENGTH(json_doc[, path])

回到 JSON XML的尺寸,其计数原则上如下:

如果是乘积绝对值,其尺寸为 1。 如果是为统计数据结构,其尺寸为为统计数据结构表达模式的个为数。 如果是并不一定,其尺寸为并不一定表达模式的个为数。 不包同上为统计数据结构为统计数据和为统计数据结构并不一定的尺寸。

mysql> select json_length('"abc"');

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

json_length('"abc"') |

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

1 |

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

1 row in set (0.00 sec)

mysql> select json_length('[1, 2, {"a": 3}]');

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

json_length('[1, 2, {"a": 3}]') |

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

3 |

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

1 row in set (0.00 sec)

mysql> select json_length('{"a": 1, "b": {"c": 30}}');

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

json_length('{"a": 1, "b": {"c": 30}}') |

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

2 |

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

1 row in set (0.00 sec)

mysql> select json_length('{"a": 1, "b": {"c": 30}}', '$.a');

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

json_length('{"a": 1, "b": {"c": 30}}', '$.a') |

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

1 |

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

1 row in set (0.00 sec)

10)JSON_TYPE(json_val)

回到 JSON 绝对值的各种类型。

mysql> select json_type('123');

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

json_type('123') |

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

INTEGER |

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

1 row in set (0.00 sec)

mysql> select json_type('"abc"');

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

json_type('"abc"') |

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

STRING |

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

1 row in set (0.00 sec)

mysql> select json_type(cast(now() as json));

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

json_type(cast(now() as json)) |

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

DATETIME |

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

1 row in set (0.00 sec)

mysql> select json_type(json_extract('{"a": [10, true]}', '$.a'));

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

json_type(json_extract('{"a": [10, true]}', '$.a')) |

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

ARRAY |

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

1 row in set (0.00 sec)

11)JSON_VALID(val)

判别任意绝对值到底必必需的 JSON XML。

mysql> select json_valid('hello'), json_valid('"hello"');

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

json_valid('hello') | json_valid('"hello"') |

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

0 | 1 |

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

1 row in set (0.00 sec)

12)JSON_TABLE(expr, path COLUMNS (column_list) [AS] alias)

从 JSON XML中会抽取为统计数据并以表格的表现形式回到。

该模板的完备语言如下:

JSON_TABLE(

expr,

path COLUMNS (column_list)

) [AS] alias

column_list:

column[, column][, ...]

column:

name FOR ORDINALITY

name type PATH string_path [on_empty] [on_error]

name type EXISTS PATH string_path

NESTED [PATH] path COLUMNS (column_list)

on_empty:

{NULL | DEFAULT json_string | ERROR} ON EMPTY

on_error:

{NULL | DEFAULT json_string | ERROR} ON ERROR

其中会,

expr:可以回到 JSON XML的操纵符。可以是一个乘积( JSON XML ),四支名或者一个模板调用( JSON_EXTRACT(t1.json_data,'$.post.comments') )。 path:JSON 的切线操纵符, column:四支的各种类型,默许表列出四种各种类型: name FOR ORDINALITY:序四支号。name 是四支名。 name type PATH string_path [on_empty] [on_error]:抽取登录切线( string_path )的表达模式。name 是四支名,type 是 MySQL 中会的模板。 name type EXISTS PATH string_path:登录切线( string_path )的表达模式应该存有。 NESTED [PATH] path COLUMNS (column_list):将为统计数据结构并不一定或为统计数据结构与来自祖父并不一定或为统计数据结构的 JSON 绝对值扁平化为四人控制器。

select *

from

json_table(

'[{"x":2, "y":"8", "z":9, "b":[1,2,3]}, {"x":"3", "y":"7"}, {"x":"4", "y":6, "z":10}]',

"$[*]" columns(

id for ordinality,

xval varchar(100) path "$.x",

yval varchar(100) path "$.y",

z_exist int exists path "$.z",

nested path '$.b[*]' columns (b INT PATH '$')

) as t;

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

id | xval | yval | z_exist | b |

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

1 | 2 | 8 | 1 | 1 |

1 | 2 | 8 | 1 | 2 |

1 | 2 | 8 | 1 | 3 |

2 | 3 | 7 | 0 | NULL |

3 | 4 | 6 | 1 | NULL |

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

5 rows in set (0.00 sec)

13)JSON_SCHEMA_VALID(schema,document)

判别 document ( JSON XML )应该充分依靠 schema ( JSON 并不一定)定义的规范决定。完备的规范决定可参考 Draft 4 of the JSON Schema specification (#draft-4)。如果不充分依靠,可通过 JSON_SCHEMA_VALIDATION_REPORT() 受益具体情况的理由。

以解释器这个 schema 为例。

set @schema = '{

"type": "object",

"properties": {

"latitude": {

"type": "number",

"minimum": -90,

"maximum": 90

},

"longitude": {

"type": "number",

"minimum": -180,

"maximum": 180

}

},

"required": ["latitude", "longitude"]

}';

它的决定如下:

document 必须是 JSON 并不一定。 JSON 并不一定必必需的两个属性是 latitude 和 longitude。 latitude 和 longitude 必须是为数绝对值各种类型,且两者的大小不一分别在 -90 ~ 90,-180 ~ 180 彼此间。

解释器通过具体情况的 document 来的测试一下。

mysql> set @document = '{"latitude": 63.444697,"longitude": 10.445118}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_schema_valid(@schema, @document);

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

json_schema_valid(@schema, @document) |

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

1 |

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

1 row in set (0.00 sec)

mysql> set @document = '{"latitude": 63.444697}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_schema_valid(@schema, @document);

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

json_schema_valid(@schema, @document) |

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

0 |

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

1 row in set (0.00 sec)

mysql> select json_pretty(json_schema_validation_report(@schema, @document))G

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

json_pretty(json_schema_validation_report(@schema, @document)): {

"valid": false,

"reason": "The JSON document location '#' failed requirement 'required' at JSON Schema location '#'",

"schema-location": "#",

"document-location": "#",

"schema-failed-keyword": "required"

}

1 row in set (0.00 sec)

mysql> set @document = '{"latitude": 91,"longitude": 0}';

Query OK, 0 rows affected (0.00 sec)

mysql> select json_schema_valid(@schema, @document);

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

json_schema_valid(@schema, @document) |

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

0 |

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

1 row in set (0.00 sec)

mysql> select json_pretty(json_schema_validation_report(@schema, @document))G

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

json_pretty(json_schema_validation_report(@schema, @document)): {

"valid": false,

"reason": "The JSON document location '#/latitude' failed requirement 'maximum' at JSON Schema location '#/properties/latitude'",

"schema-location": "#/properties/latitude",

"document-location": "#/latitude",

"schema-failed-keyword": "maximum"

}

1 row in set (0.00 sec)

八、揭示

如果要适用 JSON 各种类型,推荐适用 MySQL 8.0。相比于 MySQL 5.7,Partial update 促使的效能提升还是十分显着的。

Partial update 在存储器变速箱层是预设打开的,binlog 中会应该打开远大于 binlog_row_value_options 。该模板预设为空,不都会打开 Partial update,指出同意设为 PARTIAL_JSON。

提醒适用 Partial update 的前提有条件。

当我们适用 JSON_CONTAINS、MEMBER OF、JSON_OVERLAPS 完形同为统计数据结构具体情况的操纵时,可适用 MySQL 8.0.17 带入的多绝对值为统计数据库来加较慢查看。

>>>>参考资料

JSON The JSON Data Type JSON Functions Upgrading JSON data stored in TEXT columns Indexing JSON documents via Virtual Columns Partial update of JSON values MySQL 8.0: InnoDB Introduces LOB Index For Faster Updates

所作丨陈臣

来源丨市民号:MySQL实弹(ID:MySQLInAction)

dbaplus社群欢迎广大技术开发人员写稿,写稿邮箱:editor@dbaplus.cn

关于我们

dbaplus社群是环绕着Database、BigData、AIOps的计数机网络专业人士社群。资深大罗志祥、技术开发超市,每天艺术类原创评论启动时,每周线上技术开发分享,每月都将技术开发沙龙,每季度GdevopsWildDAMS产业大都会。

关注市民号【dbaplus社群】,受益更加多原创技术开发评论和新歌方法上传

北京白癜风专科医院哪里好
常州妇科医院哪家比较专业
太原牛皮癣医院哪里比较好
贵州男科医院专家预约挂号
武汉看白癜风去什么医院最好
咳嗽有痰用急支糖浆还是川贝枇杷膏
先诺特韦片
阳了吃什么药
药品差比价
急支糖浆的功效和作用

上一篇: 精达股份8年末5日主力资金净卖出924.60万元

下一篇: 4款MacOS端强悍且实用的PC软件分享

友情链接