介绍

从5.7版本开始,MySQL支持JSON类型字段,如果值是有效的JSON值,则插入成功,但如果该值不是有效的JSON字符串,则报错:

  1. mysql> CREATE TABLE t1 (jdoc JSON);
  2. mysql> INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
  3. mysql> INSERT INTO t1 VALUES('[1, 2,');
  4. ERROR 3140 (22032): Invalid JSON text: "Invalid value." at position 6 in value for column 't1.jdoc'.

JSON_TYPE函数,输入一个JSON字符串,返回JSON类型,如果输入的是无效JSON字符串,则报错:

  1. mysql> SELECT JSON_TYPE('["a", "b", 1]');
  2. +----------------------------+
  3. | JSON_TYPE('["a", "b", 1]') |
  4. +----------------------------+
  5. | ARRAY |
  6. +----------------------------+
  7. mysql> SELECT JSON_TYPE('"hello"');
  8. +----------------------+
  9. | JSON_TYPE('"hello"') |
  10. +----------------------+
  11. | STRING |
  12. +----------------------+
  13. mysql> SELECT JSON_TYPE('hello');
  14. ERROR 3141 (22032): Invalid JSON text in argument 1 to function json_type: "Invalid value." at position 0.

JSON_ARRAY函数,用于构造一个JSON数组:

  1. mysql> SELECT JSON_ARRAY("a", "b", "c");
  2. +---------------------------+
  3. | JSON_ARRAY("a", "b", "c") |
  4. +---------------------------+
  5. | ["a", "b", "c"] |
  6. +---------------------------+
  7. 1 row in set (0.00 sec)
  8. mysql> SELECT JSON_ARRAY('a', 1, NOW());
  9. +----------------------------------------+
  10. | JSON_ARRAY('a', 1, NOW()) |
  11. +----------------------------------------+
  12. | ["a", 1, "2015-07-27 09:43:47.000000"] |
  13. +----------------------------------------+

JSON_OBJECT函数,用于构造一个JSON对象:

  1. mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc');
  2. +---------------------------------------+
  3. | JSON_OBJECT('key1', 1, 'key2', 'abc') |
  4. +---------------------------------------+
  5. | {"key1": 1, "key2": "abc"} |
  6. +---------------------------------------+

JSON_OBECTJSON_ARRAY也可以配合嵌套使用:

  1. mysql> select JSON_OBJECT("key1", JSON_ARRAY("a", "b"), "key2", JSON_OBJECT("key2-1", "a"));
  2. +-------------------------------------------------------------------------------+
  3. | JSON_OBJECT("key1", JSON_ARRAY("a", "b"), "key2", JSON_OBJECT("key2-1", "a")) |
  4. +-------------------------------------------------------------------------------+
  5. | {"key1": ["a", "b"], "key2": {"key2-1": "a"}} |
  6. +-------------------------------------------------------------------------------+

JSON_MERGE函数,将两个或多个JSON合并:

  1. mysql> SELECT JSON_MERGE('["a", 1]', '{"key": "value"}');
  2. +--------------------------------------------+
  3. | JSON_MERGE('["a", 1]', '{"key": "value"}') |
  4. +--------------------------------------------+
  5. | ["a", 1, {"key": "value"}] |
  6. +--------------------------------------------+
  7. mysql> SELECT JSON_MERGE(JSON_ARRAY(1,2,3), JSON_ARRAY(4,5));
  8. +------------------------------------------------+
  9. | JSON_MERGE(JSON_ARRAY(1,2,3), JSON_ARRAY(4,5)) |
  10. +------------------------------------------------+
  11. | [1, 2, 3, 4, 5] |
  12. +------------------------------------------------+

自动规范化与合并

当对象的值重复时,会自动丢弃重复的,如下:

  1. mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
  2. +------------------------------------------------------+
  3. | JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
  4. +------------------------------------------------------+
  5. | {"key1": 1, "key2": "abc"} |
  6. +------------------------------------------------------+

对象的自动合并:

  1. mysql> SELECT JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}');
  2. +----------------------------------------------------+
  3. | JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}') |
  4. +----------------------------------------------------+
  5. | {"a": [1, 4], "b": 2, "c": 3} |
  6. +----------------------------------------------------+

数组的自动合并:

  1. mysql> SELECT JSON_MERGE('[1, 2]', '["a", "b"]', '[true, false]');
  2. +-----------------------------------------------------+
  3. | JSON_MERGE('[1, 2]', '["a", "b"]', '[true, false]') |
  4. +-----------------------------------------------------+
  5. | [1, 2, "a", "b", true, false] |
  6. +-----------------------------------------------------+
  7. mysql> SELECT JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}');
  8. +------------------------------------------------+
  9. | JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}') |
  10. +------------------------------------------------+
  11. | [10, 20, {"a": "x", "b": "y"}] |
  12. +------------------------------------------------+
  13. mysql> SELECT JSON_MERGE('1', '2');
  14. +----------------------+
  15. | JSON_MERGE('1', '2') |
  16. +----------------------+
  17. | [1, 2] |
  18. +----------------------+

在进行插入操作时,会自动规范化与合并:

  1. mysql> CREATE TABLE t1 (c1 JSON);
  2. mysql> INSERT INTO t1 VALUES
  3. > ('{"x": 17, "x": "red"}'),
  4. > ('{"x": 17, "x": "red", "x": [3, 5, 7]}');
  5. mysql> SELECT c1 FROM t1;
  6. +-----------+
  7. | c1 |
  8. +-----------+
  9. | {"x": 17} |
  10. | {"x": 17} |
  11. +-----------+

搜索与修改

JSON路径表达式获取JSON中的一个值,以指定在该文档中的操作位置。例如,以下操作获取JSON对象中Key值为name的内容:

  1. mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
  2. +---------------------------------------------------------+
  3. | JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
  4. +---------------------------------------------------------+
  5. | "Aztalan" |
  6. +---------------------------------------------------------+

以下操作将JSON文档的第一个值设置为a

  1. mysql> SELECT JSON_SET('"x"', '$[0]', 'a');
  2. +------------------------------+
  3. | JSON_SET('"x"', '$[0]', 'a') |
  4. +------------------------------+
  5. | "a" |
  6. +------------------------------+

可以包含通配符或通配符*

  • .[*]匹配JSON对象中所有成员的值
  • [*]匹配JSON数组中所有元素的值

示例JSON文档:

  1. [3, {"a": [5, 6], "b": 10}, [99, 100]]
  • $[0]计算结果为 3
  • $[1]计算结果为 {"a": [5, 6], "b": 10}
  • $[2]计算结果为 [99, 100]
  • $[3]计算为 NULL(不存在)
  • $[1].a计算结果为 [5, 6]
  • $[1].a[1]计算结果为 6
  • $[1].b计算结果为 10
  • $[2][0]计算结果为 99

使用通配符获取多个结果示例:

  1. mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
  2. +---------------------------------------------------------+
  3. | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
  4. +---------------------------------------------------------+
  5. | [1, 2, [3, 4, 5]] |
  6. +---------------------------------------------------------+
  7. mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
  8. +------------------------------------------------------------+
  9. | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
  10. +------------------------------------------------------------+
  11. | [3, 4, 5] |
  12. +------------------------------------------------------------+

在下面的示例中,$**.b相当于生成了$.a.b$.c.b,它会匹配JSON对象中所有属性名称为b的值:

  1. mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
  2. +---------------------------------------------------------+
  3. | JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
  4. +---------------------------------------------------------+
  5. | [1, 2] |
  6. +---------------------------------------------------------+

使用JSON_SET可以修改JSON文档中指定路径的值:

  1. mysql> SELECT JSON_SET('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2);
  2. +---------------------------------------------------------------------------------+
  3. | JSON_SET('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2) |
  4. +---------------------------------------------------------------------------------+
  5. | ["a", {"b": [1, false]}, [10, 20, 2]] |
  6. +---------------------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)

使用JSON_INSERT可以在JSON文档中指定路径插入值,它只会添加新的值,不会替换已存在的值:

  1. mysql> SELECT JSON_INSERT('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2);
  2. +------------------------------------------------------------------------------------+
  3. | JSON_INSERT('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2) |
  4. +------------------------------------------------------------------------------------+
  5. | ["a", {"b": [true, false]}, [10, 20, 2]] |
  6. +------------------------------------------------------------------------------------+

使用JSON_REPLACE替换已经存在的值:

  1. mysql> SELECT JSON_REPLACE('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2);
  2. +-------------------------------------------------------------------------------------+
  3. | JSON_REPLACE('["a", {"b": [true, false]}, [10, 20]]', '$[1].b[0]', 1, '$[2][2]', 2) |
  4. +-------------------------------------------------------------------------------------+
  5. | ["a", {"b": [1, false]}, [10, 20]] |
  6. +-------------------------------------------------------------------------------------+

使用JSON_REMOVE删除JSON文档中指定路径的值:

  1. mysql> SELECT JSON_REMOVE('["a", {"b": [true, false]}, [10, 20]]', '$[2]', '$[1].b[1]', '$[1].b[1]');;
  2. +----------------------------------------------------------------------------------------+
  3. | JSON_REMOVE('["a", {"b": [true, false]}, [10, 20]]', '$[2]', '$[1].b[1]', '$[1].b[1]') |
  4. +----------------------------------------------------------------------------------------+
  5. | ["a", {"b": [true]}] |
  6. +----------------------------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)