Mysql json类型

5.7版本支持
原生json类型代替BLOB类型
json数据有效性检查
查询性能提升:不需要遍历所有字符串才能找到数据
支持部分属性索引

1. json格式范例

2. 结构化与非结构化

结构化:二维表结构(行和列) ? 使用SQL语句进行操作
非结构化:使用Key-Value格式定义数据,无结构定义 ? Value可以嵌套Key-Value格式的数据 ? 使用JSON进行实现

SQL创建User表
create table user (
id bigint not null auto_increment,
user_name varchar(10),
age int,
primary key(id) );

JSON定义的User表 ==类似mongodb文档数据库
db.user.insert({ user_name:"tom", age:30 })
db.createCollection("user")

3. json 操作例子

(1)json入门
创建带json字段的表
create table user (
uid int auto_increment,
data json,
primary key(uid));

插入json数据
insert into user values(
null,
‘{"name":"tom",
"age":18,
"address":"sz"
}‘
);

"[email protected]:mysql.sock  [json]>select * from user;
+-----+---------------------------------------------+
| uid | data                                        |
+-----+---------------------------------------------+
|   1 | {"age": 18, "name": "tom", "address": "sz"} |
+-----+---------------------------------------------+
1 row in set (0.01 sec)

insert into user values("age":28,
"mail":"[email protected]"
br/>null,
‘{"name":"jim",
"age":28,
"mail":"[email protected]"
}‘
);

insert into user values ( null, "can you insert it?"); -- 无法插入,因为是JSON类型

4、json常用函数介绍

(1)json_extract
使用json_extract提取数据
原型 : JSON_EXTRACT(json_doc, path[, path] ...)
从list中抽取 下标 为1的元素(下标从0开始)
select json_extract(‘[10, 20, [30, 40]]‘, ‘$[1]‘);

"[email protected]:mysql.sock  [json]>select json_extract(‘[10, 20, [30, 40]]‘, ‘$[1]‘);
+--------------------------------------------+
| json_extract(‘[10, 20, [30, 40]]‘, ‘$[1]‘) |
+--------------------------------------------+
| 20                                         |
+--------------------------------------------+
1 row in set (0.00 sec)

select json_extract(data, ‘$.name‘),json_extract(data, ‘$.address‘)from user;

"[email protected]:mysql.sock  [json]>select json_extract(data, ‘$.name‘),json_extract(data, ‘$.address‘)from user;
+------------------------------+---------------------------------+
| json_extract(data, ‘$.name‘) | json_extract(data, ‘$.address‘) |
+------------------------------+---------------------------------+
| "tom"                        | "sz"                            |
| "jim"                        | NULL                            |
+------------------------------+---------------------------------+
2 rows in set (0.00 sec)

(2)json_object
将list(K-V对)封装成json格式
原型 : JSON_OBJECT([key, val[, key, val] ...])
select json_object("name", "jery", "email", "[email protected]", "age",33);

"[email protected]:mysql.sock  [json]>select json_object("name", "jery", "email", "[email protected]", "age",33);
+----------------------------------------------------------------+
| json_object("name", "jery", "email", "[email protected]", "age",33) |
+----------------------------------------------------------------+
| {"age": 33, "name": "jery", "email": "[email protected]"}           |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

insert into user values (
null,
json_object("name", "jery", "email", "[email protected]", "age",33)
);

(3)json_insert
插入数据
原型 : JSON_INSERT(json_doc, path, val[, path, val] ...)

set @j = ‘{ "a": 1, "b": [2, 3]}‘;
select json_insert(@j, ‘$.a‘, 10, ‘$.c‘, ‘[true, false]‘);

"[email protected]:mysql.sock  [json]>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)

update user set data = json_insert(data, "$.address_2", "BJ") where uid = 1;
select * from user;

(4)json_merge
合并数据并返回。注意:原数据不受影响
原型 : JSON_MERGE(json_doc, json_doc[, json_doc] ...)
-- 原来有两个JSON
select json_merge(‘{"name": "x"}‘, ‘{"id": 47}‘);

"[email protected]:mysql.sock  [json]>select json_merge(‘{"name": "x"}‘, ‘{"id": 47}‘);
+-------------------------------------------+
| json_merge(‘{"name": "x"}‘, ‘{"id": 47}‘) |
+-------------------------------------------+
| {"id": 47, "name": "x"}                   |
+-------------------------------------------+
1 row in set (0.00 sec)

(5)json_array_append
追加数据 --
原型 : JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)
-- json_append 在5.7.9 中重命名为 json_array_append

set @j = ‘["a", ["b", "c"], "d"]‘; -- 下标为1的元素中只有["b", "c"]
select json_array_append(@j, ‘$[1]‘, 1);

"[email protected]:mysql.sock [json]>select json_array_append(@j, ‘$[1]‘, 1);
+----------------------------------+
| json_array_append(@j, ‘$[1]‘, 1) |
+----------------------------------+
| ["a", ["b", "c", 1], "d"] |
+----------------------------------+
1 row in set (0.00 sec)

(6)json_remove
从json记录中删除数据
-- 原型 : JSON_REMOVE(json_doc, path[, path] ...)
set @j = ‘["a", ["b", "c"], "d"]‘;
select json_remove(@j, ‘$[1]‘);
update user set data = json_remove(data, "$.address_2") where uid = 1;

5. json创建索引

JSON 类型数据本身 无法直接 创建索引,
需要将需要索引的JSON数据重新生成虚拟列(Virtual Columns) 之后,对该列进行索引
(1)新建表时创建JSON索引

#抽取data中的name, 生成新的一列,名字为gen_col并将gen_col 作为索引
create table test_inex_1(
data json,
gen_col varchar(10) generated always as (json_extract(data, ‘$.name‘)),
index idx (gen_col)
);

show create table test_inex_1;

"[email protected]:mysql.sock [json]>show create table test_inex_1\G;
1. row
Table: test_inex_1
Create Table: CREATE TABLE test_inex_1 (
data json DEFAULT NULL,
gen_col varchar(10) GENERATED ALWAYS AS (json_extract(data,‘$.name‘)) VIRTUAL,
KEY idx (gen_col)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

insert into test_inex_1(data) values (‘{"name":"tom", "age":18, "address":"SH"}‘);
insert into test_inex_1(data) values (‘{"name":"jim", "age":28, "address":"SZ"}‘);
select * from test_inex_1;

"[email protected]:mysql.sock  [json]>select * from test_inex_1;
+---------------------------------------------+---------+
| data                                        | gen_col |
+---------------------------------------------+---------+
| {"age": 18, "name": "tom", "address": "SH"} | "tom"   |
| {"age": 28, "name": "jim", "address": "SZ"} | "jim"   |
+---------------------------------------------+---------+
2 rows in set (0.00 sec)

select json_extract(data,"$.name") as username from test_inex_1 where gen_col=‘"tom"‘; -- 使用‘"tome"‘,用单引号括起来
explain select json_extract(data,"$.name") as username from test_inex_1 where gen_col=‘"tom"‘\G

(2)修改已存在的表创建JSON索引
show create table user;
select from user;
alter table user add user_name varchar(32) generated always as (json_extract(data,"$.name")) virtual;
select user_name from user;
alter table user add index idx(user_name);
select
from user where user_name=‘"tom"‘; -- 加单引号
explain select * from user where user_name=‘"tom"‘\G

6. 附录

-- 老师演示JSON的SQL -drop table if exists User;
CREATE TABLE User (
uid BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32) NOT NULL,
email VARCHAR(256) NOT NULL,
address VARCHAR(512) NOT NULL,
UNIQUE KEY (name),
UNIQUE KEY (email) );
INSERT INTO User VALUES (NULL,‘David‘,‘[email protected]‘,‘Shanghai ...‘); INSERT INTO User VALUES (NULL,‘Amy‘,‘[email protected]‘,‘Beijing ...‘);
INSERT INTO User VALUES (NULL,‘Tom‘,‘[email protected]‘,‘Guangzhou ...‘);
SELECT * FROM User;
ALTER TABLE User ADD COLUMN address2 VARCHAR(512) NOT NULL; ALTER TABLE User ADD COLUMN passport VARCHAR(64) NOT NULL;

DROP TABLE IF EXISTS UserJson;
CREATE TABLE UserJson(
uid BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
data JSON );
truncate table UserJson;
insert into UserJson SELECT uid,JSON_OBJECT(‘name‘,name,‘email‘,email,‘address‘,address) AS data FROM User;
SELECT * FROM UserJson;
SELECT uid,JSON_EXTRACT(data,‘$.address2‘) from UserJson;
UPDATE UserJson set data = json_insert(data,"$.address2","HangZhou ...") where uid = 1;
SELECT JSON_EXTRACT(data,‘$.address[1]‘) from UserJson;
select json_merge(JSON_EXTRACT(data,‘$.address‘) ,JSON_EXTRACT(data,‘$.address2‘)) from UserJson;

begin;
UPDATE UserJson set data = json_array_append(data,"$.address",JSON_EXTRACT(data,‘$.address2‘)) where JSON_EXTRACT(data,‘$.address2‘) IS NOT NULL AND uid >0;
select JSON_EXTRACT(data,‘$.address‘) from UserJson;
UPDATE UserJson set data = JSON_REMOVE(data,‘$.address2‘) where uid>0;
commit;

Mysql json类型

原文地址:http://blog.51cto.com/7038006/2072655

时间: 2024-11-04 00:14:59

Mysql json类型的相关文章

MySQL 5.7新支持--------Json类型实战

1. 背景 * 在MySQL 5.7.8中,MySQL支持由RFC 7159定义的本地JSON数据类型,它支持对JSON(JavaScript对象标记)文档中的数据进行有效访问. * MySQL会对DML JSON数据自动验证.无效的DML JSON数据操作会产生错误. * 优化的存储格式.存储在JSON列中的JSON文档转换为一种内部格式,允许对Json元素进行快速读取访问. * MySQL Json类型支持建立索引增加查询性能提升. 2. Json类型所需的存储空间和值范围 类型 占用字节

使用mysql innodb 使用5.7的json类型遇到的坑和解决办法

---------------------------------------------- #查询JSON的某个字段 select data -> '$.Host' from temp #创建虚拟列 ALTER TABLE temp ADD host varchar(128) GENERATED ALWAYS AS (json_extract(data,'$.Host')) VIRTUAL; #给虚拟列创建索引 ALTER TABLE temp ADD INDEX index_temp_hos

使用Python向MySQL数据库中存入json类型数据

0.说明 因为出于个人项目的需要,获取到的数据都是json类型的,并且都要存入MySQL数据库中,因为json类型数据不像一般的文本数据,所以在存入MySQL时需要注意的问题很多. 在网上找了很多方法,整理了一下比较实用可靠的,总结下来就是下面的过程: MySQL表中需要保证存储json数据的列类型为BLOB: 使用sql语句时,使用MySQLdb.excape_string函数来对json数据进行转义: 查询数据时,将结果使用json.loads就能够得到原来的Python数据类型: 下面就来

Mybatis和Mysql的Json类型

Mysql5.7新增加了Json类型字段,但是目前Mybatis中并不支持 1.新建MybatisJsonTypeHandler.java import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.

mysql中生成列与JSON类型的索引

MySQL中支持生成列,生成列的值是根据列定义中包含的表达式计算的. 一个简单的例子来认识生成列! CREATE TABLE triangle( sidea DOUBLE, sideb DOUBLE, sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb)) ); INSERT INTO triangle(sidea, sideb) VALUES(3,4),(6,8),(5,12); mysql> select * from triangle;

【Mysql】Mysql Json类型或Text类型可以建索引吗?

一.JSON类型 答案是不可以 为Json类型建索引会报错 mysql> CREATE INDEX idx1 ON user (card_pay_data(10)); ERROR 3152 (42000): JSON column 'card_pay_data' cannot be used in key specification. 二.text类型 答案是可以的,但是需要指定长度 mysql> CREATE INDEX idx2 ON user (tests); ERROR 1170 (4

MySQL对JSON类型UTF-8编码导致中文乱码探讨

前言 继上文发表之后,结合评论意见并亲自验证最终发现是编码的问题,但是对于字符编码还是有点不解,于是乎,有了本文,我们来学习字符编码,在学习的过程中,我发现对于MySQL中JSON类型的编码导致数据中文出现乱码还有可深挖之处,接下来我们来分析一下,若有错误之处,还请批评指出. 字符编码 评论中指出任何不在基本多文本平面的Unicode字符,都无法使用MySQL的utf8字符集存储,包括Emoji 表情(Emoji 是一种特殊的Unicode 编码,常见于IOS和Android 手机上)和很多不常

MYSQL中的JSON类型

JSON是mysql5.7新增的数据类型,打破了我对mysql数据存储的概念,在列中还能存储结构化的数据. 官方文档是很好理解的学习资源. JSON类型格式,虽然插入的时候我们可以用字符串表示插入,但是mysql内部会被识别为json格式,也有一系列特殊处理方法. 在这之前,对mysql处理json数据的path类型的参数需要有个了解 '$'这个代表json对象本身 '$.a'代表json对象的key为a的对象 '$[0]',json对象是个数组时,为数组的第一个元素 当然表达式可以串联,如'$

mysql - varchar类型与数字的比较和转换

mysql - varchar类型与数字的比较和转换 convert(对象, 目标类型)是mysql中常用的类型转换对象函数.eg: select convert('1.123', decimal(10.4)),结果就是1.1230.对象可以用列名替代. 前两天发现,一个小伙伴之前设计表时把某个表数据类型设计成了varchar,实际用于存储Decimal.我需要用其数据进行过滤筛选 如果文章内容有问题,欢迎评论或与我进行讨论(请注明原因): mail: [email protected] 微信: