MySQL数据类型(3)- JSON

最后更新:2018-06-13

JSON数组和对象可以包含标量值是字符串或数字,JSON null文本,或者JSON布尔真或假的文字。在JSON对象键必须是字符串。时间(日期,时间或日期)标值也是允许的

1. 创建JSON列

CREATE TABLE test ( id INT NOT NULL auto_increment, ext json, PRIMARY KEY ( id ) );

2. 插入

INSERT INTO test ( ext )
VALUES
	( '{"name":"Edgar","age":30}' ),
	( '{"name":"Leona","age":30}' );

3. MySQL的JSON构造函数

JSON_ARRAY

INSERT INTO test ( ext )
VALUES
	( JSON_ARRAY ( 1, "abc", NULL, TRUE, CURTIME( ) ) );

[1, “abc”, null, true, “03:02:12.000000”]

查询

SELECT JSON_EXTRACT(ext, '$[1]') FROM test where id = 3
--返回 "abc"

JSON_OBJECT

INSERT INTO test ( ext )
VALUES
	( JSON_OBJECT ( 'id', 87, 'name', 'carrot' ) );

{“id”: 87, “name”: “carrot”}

JSON_MERGE

INSERT INTO test ( ext )
VALUES
	( JSON_MERGE('[1, 2]', '[true, false]')),
	(JSON_MERGE('{"name": "x"}', '{"id": 47}')),
	(JSON_MERGE('1', 'true')),
	(JSON_MERGE('[1, 2]', '{"id": 47}'));

[1, 2, true, false] {“id”: 47, “name”: “x”} [1, true] [1, 2, {“id”: 47}]

查询

SELECT JSON_EXTRACT(ext, '$[2].id') FROM test where id = 8

4. 提取JSON值

SELECT
	id,
	json_extract ( ext, '$.name' ) AS NAME,
	json_extract ( ext, '$.age' ) age 
FROM
	test;
	
SELECT JSON_EXTRACT(ext, '$[1]') FROM test where id = 3
SELECT JSON_EXTRACT(ext, '$[2].id') FROM test where id = 8

ext->’$.age’与等效

SELECT
	id,
	json_extract ( ext, '$.name' ) AS NAME,
	ext->'$.age' age
FROM
	test;

5. 提取JSON的KEY

SELECT
	id,
	json_keys ( ext ) 
FROM
	test

返回的json_keys是一个数组

6. JSON_INSERT

增加了新的值,但不会取代现有的值

UPDATE test 
SET ext = JSON_INSERT( ext, '$.name', "Edgar615", '$.address', 'wuhan' ) 
WHERE
	id = 1;

执行完之后,JSON的name并没变,只是新加入了一个address

{"age": 30, "name": "Edgar", "address": "wuhan"}

7. JSON_SET 更新K-V

UPDATE test 
SET ext = JSON_SET( ext, '$.name', "Brena", '$.address', 'wuhan' ) 
WHERE
	id = 2;

执行完之后,JSON的name变了,并且新加入了一个address

{"age": 30, "name": "Brena", "address": "wuhan"}

8. JSON_REMOVE 删除KEY

UPDATE test 
SET ext = JSON_REMOVE( ext, '$.name', '$.address' ) 
WHERE
	id = 2;

执行完之后,JSON的只剩下{“age”: 30}

UPDATE test 
SET ext = JSON_REMOVE( ext, '$[1]' ) 
WHERE
	id = 8;
	
UPDATE test 
SET ext = JSON_REMOVE( ext, '$[1].id' ) 
WHERE
	id = 8;

[1, {}]

9. JSON_REPLACE

替换现有的值,并忽略新值:

UPDATE test 
SET ext = JSON_REPLACE( ext, '$.age', 10, '$.name', 'Leona' ) 
WHERE
	id = 2;

10. JSON_TYPE

返回JSON的类型

SELECT json_type(ext) from test

11. 比较

JSON值可使用进行比较 =,<,<=,>,> =,<>,!=和 <=> 运算。 http://www.huzs.net/?p=2318

12. 查询条件

SELECT * from test where json_extract(ext,'$.age') > 10
SELECT * from test where ext->'$.age' > 10

上面的查询会全表扫描,为了提高效率,需要对检索的key创建虚拟列,然后再虚拟列上创建索引

EXPLAIN SELECT * from test where ext->'$.age' > 10

创建虚拟列

ALTER TABLE test ADD age_virtual int GENERATED ALWAYS AS (ext->'$.age') VIRTUAL;

对虚拟列创建索引

CREATE INDEX age_virtual_index  ON test(age_virtual);

WHERE中使用虚拟列

SELECT * from test where age_virtual > 10

JSON_CONTAINS

select * from commodity where json_contains(ext, JSON_ARRAY (1), '$.physique')
Edgar

Edgar
一个略懂Java的小菜比