mysql 之 json 数据类型的使用及高效检索(配合虚拟列 virtual generated column)

栏目: 数据库 · 发布时间: 5年前

内容简介:mysql 5.7+ 版本开始支持 json 数据类型,可以方便的存储JSON格式的数据,同时配合虚拟列 (virtual generated column),可以方便的为 json 列数据的某属性映射虚拟列,建立索引,高效检索。方法:json_array() / json_object()json_array / json_object 用于组装 json 数据,json 说的简单些json就是由标量(int, float, string) + 数组 + 对象组合而成的,这两个函数可以方便的用于构造数组和

mysql 5.7+ 版本开始支持 json 数据类型,可以方便的存储JSON格式的数据,同时配合虚拟列 (virtual generated column),可以方便的为 json 列数据的某属性映射虚拟列,建立索引,高效检索。

构造json数据

方法:json_array() / json_object()

json_array / json_object 用于组装 json 数据,json 说的简单些json就是由标量(int, float, string) + 数组 + 对象组合而成的,这两个函数可以方便的用于构造数组和对象的json格式串

json_array(item1, item2, item3, ...)
    =>
[item1, item2, item3]

json_object(key1, val1[, [key2, val2]...])
    => 
{"key1": "val1", "key2": "val2",...}

使用场景例如:

select json_object(
    "username", "big_cat",
    "favorites", json_array(
        json_object("article_id", 1, "favorited_at", "2019-01-18"),
        json_object("article_id", 2, "favorited_at", "2019-01-18"),
        json_object("article_id", 3, "favorited_at", "2019-01-18"),
        json_object("article_id", 4, "favorited_at", "2019-01-18")
    )
);
// result
{
    "username": "big_cat",
    "favorites": [
        {"article_id": 1, "favorited_at": "2019-01-18"},
        {"article_id": 2, "favorited_at": "2019-01-18"},
        {"article_id": 3, "favorited_at": "2019-01-18"},
        {"article_id": 4, "favorited_at": "2019-01-18"}
    ]
}

读取json数据

方法:json_extract() / col ->"$.{property_name}"

json_extract 用于读取 json 列的某字段,或者也可以使用 col ->"$.{property_name}" 的方式访问

json_extract(`col`, '$.{property_name}') / `col`->'$.{property_name}'
create table `users` (
`id` int unsigned not null auto_increment primary key,
`doc` json
);

insert into `users`(`doc`)
values (json_object("name", "big_cat", "age", 28)), ('{"name": "james", "age": 29}');

select json_extract(`doc`, "$.name") as `name`, json_extract(`doc`, "$.age") as `age` from `users`;
select `doc`->"$.name" as `name`, `doc`->"$.age" as `age` from `users`;

高效检索json数据

mysql 提供的一些函数是可以方便我们条件检索json数据的,但无法使用索引,数据量大的时候难免低效。

select id, doc->"$.age" from users where json_extract(doc, "$.name") = "big_cat";
select id, doc->"$.age" from users where doc->"$.name" = "big_cat";

这时我们可以利用同 json 一同新增的特性:虚拟列(virtual generated column)。

将需要参与检索的 json 属性映射为 虚拟列,在虚拟列上建立索引,便可参与高效检索。

另外补充一下,在 mysql 5.7+中,支持两种Generated Column,即Virtual Generated Column和Stored Generated Column。前者不存储元数据,后者会将 expression 的计算结果实际的存储下来。其实二者性能差距并不大,若对二者建立索引进行检索操作,前者性能可能会略低于后者,因为前者要对结果集即时的进行 expression 的演算,但后者需要消耗额外的存储空间。

需要注意的有:不存储数据的特性也导致只能在虚拟列上建立二级索引,插入数据时不可以向虚拟列插入数值(mysql自行负责演算)。

#虚拟列创建

ALTER TABLE `table_name` ADD COLUMN `col_name` <type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ]
[ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]
# 为 user 表的 json 字段的 name 创建虚拟列
alter table `users` add column `user_name` varchar(10) generated always as (`doc`->"$.name");
# 为虚拟列添加索引
alter table `users` add index `index_u_n`(`user_name`);
# 检索时可以使用索引
explain select `id`, `user_name`, `doc`->"$.age" as `age` from `users` where `user_name` = "big_cat" \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: users
   partitions: NULL
         type: ref
possible_keys: index_u_n
          key: index_u_n
      key_len: 43
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

下面直接对 json 解析检索的方式是无法用到索引的

explain select id from users where doc->"$.user_name" = "big_cat" \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: users
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)
explain select id from users where json_extract(`doc`, '$.username') = "big_cat" \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: users
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

还有其他 json 的使用这里就不说明了,大家可以参考一下文章:

mysql json 使用 类型 查询 函数: https://www.cnblogs.com/ooo0/...

MySQL 5.7 虚拟列 (virtual columns): https://www.cnblogs.com/raich...

MySQL 5.7原生JSON格式支持: https://www.cnblogs.com/zouca...


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算理论导引

计算理论导引

[美]Michael Sipser / 张立昂、王捍贫、黄雄 / 机械工业出版社 / 2000-2 / 30.00元

本书由计算理论领域的知名权威Michael Sipser撰写。他以独特的视角,综合地描述了计算机科学理论,并以清新的笔触、生动的语言给出了宽泛的数学理论,而并非拘泥于某些低层次的技术细节。在证明之前,均有“证明思路”,帮助读者理解数学形式下蕴涵的概念。同样,对于算法描述,均以直观的文字,而非伪代码给出,从而将注意力集中于算法本身,而不是某些模型。本书的内容包括三个部分:自动机与语言、可计算性理论和一起来看看 《计算理论导引》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具