MySQL数据类型之JSON

比眉伴天荒 2023-10-16 14:22 90阅读 0赞

MySQL数据类型之JSON

SON类型是MySQL 5.7版本新增的数据类型,用好JSON数据类型可以有效解决很多业务中实际问题。

使用JSON数据类型,推荐用MySQL 8.0.17以上的版本,性能更好,同时也支持Multi-Valued Indexes;

JSON数据类型的好处是无须预先定义列,数据本身就具有很好的描述性;

不要将有明显关系型的数据用JSON存储,如用户余额、用户姓名、用户身份证等,这些都是每个用户必须包含的数据;

JSON数据类型推荐使用在不经常更新的静态数据存储。

JSON数据类型

  1. mysql> create table json_user(id int primary key auto_increment, data json);
  2. Query OK, 0 rows affected (0.09 sec)
  3. mysql> insert into json_user values(0, '{
  4. "name":"morris","age":18,"address":"china"}');
  5. Query OK, 1 row affected (0.03 sec)
  6. mysql> insert into json_user values(0, '{
  7. "name":"tom","age":16,"mail":"tomcat@google.com"}');
  8. Query OK, 1 row affected (0.01 sec)
  9. mysql> select * from json_user;
  10. +----+---------------------------------------------------------+
  11. | id | data |
  12. +----+---------------------------------------------------------+
  13. | 1 | {
  14. "age": 18, "name": "morris", "address": "china"} |
  15. | 2 | {
  16. "age": 16, "mail": "tomcat@google.com", "name": "tom"} |
  17. +----+---------------------------------------------------------+
  18. 2 rows in set (0.01 sec)

常见JSON函数的使用
json_extract抽取字段

  1. mysql> select json_extract('[1, 2, 3, [4, 5]]', '$[1]');
  2. +-------------------------------------------+
  3. | json_extract('[1, 2, 3, [4, 5]]', '$[1]') |
  4. +-------------------------------------------+
  5. | 2 |
  6. +-------------------------------------------+
  7. 1 row in set (0.02 sec)
  8. mysql> select json_extract('{
  9. "age": 18, "name": "morris", "address": "china"}', '$.name');
  10. +-----------------------------------------------------------------------------+
  11. | json_extract('{
  12. "age": 18, "name": "morris", "address": "china"}', '$.name') |
  13. +-----------------------------------------------------------------------------+
  14. | "morris" |
  15. +-----------------------------------------------------------------------------+
  16. 1 row in set (0.00 sec)
  17. mysql> select data->"$.name" from json_user;
  18. +----------------+
  19. | data->"$.name" |
  20. +----------------+
  21. | "morris" |
  22. | "tom" |
  23. +----------------+
  24. 2 rows in set (0.00 sec)

json_object将对象转为json

  1. mysql> select json_object('name','bob','age','22','email','bob@sina.com');
  2. +-------------------------------------------------------------+
  3. | json_object('name','bob','age','22','email','bob@sina.com') |
  4. +-------------------------------------------------------------+
  5. | {
  6. "age": "22", "name": "bob", "email": "bob@sina.com"} |
  7. +-------------------------------------------------------------+
  8. 1 row in set (0.01 sec)

json_insert插入数据
key存在则忽略,不存在则插入。

  1. mysql> select json_insert('{
  2. "age": 18, "name": "morris", "address": "china"}', '$.male', 'male', '$.age', 22);
  3. +-------------------------------------------------------------------------------------------------+
  4. | json_insert('{
  5. "age": 18, "name": "morris", "address": "china"}', '$.male', 'male', '$.age', 22) |
  6. +-------------------------------------------------------------------------------------------------+
  7. | {
  8. "age": 18, "male": "male", "name": "morris", "address": "china"} |
  9. +-------------------------------------------------------------------------------------------------+
  10. 1 row in set (0.00 sec)

json_merge合并数据
json_merge(已不推荐使用)与json_merge_preserve类似,相同的key会合并为数组。

json_merge_patch中相同的key会使用后面的key替换前面的key。

  1. mysql> select json_merge_patch('{
  2. "name": "enjoy"}', '{
  3. "id": 47, "name":"morris"}');
  4. +----------------------------------------------------------------------+
  5. | json_merge_patch('{
  6. "name": "enjoy"}', '{
  7. "id": 47, "name":"morris"}') |
  8. +----------------------------------------------------------------------+
  9. | {
  10. "id": 47, "name": "morris"} |
  11. +----------------------------------------------------------------------+
  12. 1 row in set (0.00 sec)
  13. mysql> select json_merge('{
  14. "name": "enjoy"}', '{
  15. "id": 47, "name":"morris"}');
  16. +----------------------------------------------------------------+
  17. | json_merge('{
  18. "name": "enjoy"}', '{
  19. "id": 47, "name":"morris"}') |
  20. +----------------------------------------------------------------+
  21. | {
  22. "id": 47, "name": ["enjoy", "morris"]} |
  23. +----------------------------------------------------------------+
  24. 1 row in set, 1 warning (0.00 sec)
  25. mysql> select json_merge_preserve('{
  26. "name": "enjoy"}', '{
  27. "id": 47, "name":"morris"}');
  28. +-------------------------------------------------------------------------+
  29. | json_merge_preserve('{
  30. "name": "enjoy"}', '{
  31. "id": 47, "name":"morris"}') |
  32. +-------------------------------------------------------------------------+
  33. | {
  34. "id": 47, "name": ["enjoy", "morris"]} |
  35. +-------------------------------------------------------------------------+
  36. 1 row in set (0.00 sec)

json_array_append后面追加元素

  1. mysql> select json_array_append('["a", "b", "c"]', "$", "x");
  2. +------------------------------------------------+
  3. | json_array_append('["a", "b", "c"]', "$", "x") |
  4. +------------------------------------------------+
  5. | ["a", "b", "c", "x"] |
  6. +------------------------------------------------+
  7. 1 row in set (0.00 sec)

json_array_insert里面插入元素

  1. mysql> select json_array_insert('["a", "b", "c"]', "$[1]", "x");
  2. +---------------------------------------------------+
  3. | json_array_insert('["a", "b", "c"]', "$[1]", "x") |
  4. +---------------------------------------------------+
  5. | ["a", "x", "b", "c"] |
  6. +---------------------------------------------------+
  7. 1 row in set (0.00 sec)

json_contains包含某个json子串

  1. mysql> select json_contains('{
  2. "a":1,"b":4}','{
  3. "a":1}');
  4. +------------------------------------------+
  5. | json_contains('{
  6. "a":1,"b":4}','{
  7. "a":1}') |
  8. +------------------------------------------+
  9. | 1 |
  10. +------------------------------------------+
  11. 1 row in set (0.00 sec)
  12. mysql> select json_contains('{
  13. "age": 18, "name": "morris", "address": "china"}', '18', '$.name');
  14. +------------------------------------------------------------------------------------+
  15. | json_contains('{
  16. "age": 18, "name": "morris", "address": "china"}', '18', '$.name') |
  17. +------------------------------------------------------------------------------------+
  18. | 0 |
  19. +------------------------------------------------------------------------------------+
  20. 1 row in set (0.00 sec)

json_array创建json数组

  1. mysql> select json_array("a", "b", "c", "d");
  2. +--------------------------------+
  3. | json_array("a", "b", "c", "d") |
  4. +--------------------------------+
  5. | ["a", "b", "c", "d"] |
  6. +--------------------------------+
  7. 1 row in set (0.00 sec)

json_contains_path判断json是否包含某个key

  1. mysql> select json_contains_path('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}', 'one', '$.a', '$.e');
  4. +----------------------------------------------------------------------------+
  5. | json_contains_path('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}', 'one', '$.a', '$.e') |
  8. +----------------------------------------------------------------------------+
  9. | 1 |
  10. +----------------------------------------------------------------------------+
  11. 1 row in set (0.01 sec)
  12. mysql> select json_contains_path('{
  13. "a": 1, "b": 2, "c": {
  14. "d": 4}}', 'all', '$.a', '$.e');
  15. +----------------------------------------------------------------------------+
  16. | json_contains_path('{
  17. "a": 1, "b": 2, "c": {
  18. "d": 4}}', 'all', '$.a', '$.e') |
  19. +----------------------------------------------------------------------------+
  20. | 0 |
  21. +----------------------------------------------------------------------------+
  22. 1 row in set (0.00 sec)

json_keys查询json所有的key

  1. mysql> select json_keys('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +----------------------------------------------+
  5. | json_keys('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +----------------------------------------------+
  9. | ["a", "b", "c"] |
  10. +----------------------------------------------+
  11. 1 row in set (0.00 sec)

json_pretty格式化json

  1. mysql> select json_pretty('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +-------------------------------------------------+
  5. | json_pretty('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +-------------------------------------------------+
  9. | {
  10. "a": 1,
  11. "b": 2,
  12. "c": {
  13. "d": 4
  14. }
  15. } |
  16. +-------------------------------------------------+
  17. 1 row in set (0.00 sec)

json_depth查询json的深度

  1. mysql> select json_depth('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +-----------------------------------------------+
  5. | json_depth('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +-----------------------------------------------+
  9. | 3 |
  10. +-----------------------------------------------+
  11. 1 row in set (0.00 sec)

json_length返回json元素的个数

  1. mysql> select json_length('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +------------------------------------------------+
  5. | json_length('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +------------------------------------------------+
  9. | 3 |
  10. +------------------------------------------------+
  11. 1 row in set (0.00 sec)
  12. ————————————————

json_remove根据key删除元素

  1. mysql> select json_remove('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}', "$.c");
  4. +-------------------------------------------------------+
  5. | json_remove('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}', "$.c") |
  8. +-------------------------------------------------------+
  9. | {
  10. "a": 1, "b": 2} |
  11. +-------------------------------------------------------+
  12. 1 row in set (0.00 sec)

json_replace替换元素

  1. mysql> select json_replace('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}', "$.c", "cc");
  4. +--------------------------------------------------------------+
  5. | json_replace('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}', "$.c", "cc") |
  8. +--------------------------------------------------------------+
  9. | {
  10. "a": 1, "b": 2, "c": "cc"} |
  11. +--------------------------------------------------------------+
  12. 1 row in set (0.01 sec)

json_search搜索元素

  1. mysql> select json_search('["abc", [{
  2. "k": "10"}, "def"], {
  3. "x":"abc"}, {
  4. "y":"bcd"}]', 'one', 'abc');
  5. +--------------------------------------------------------------------------------------+
  6. | json_search('["abc", [{
  7. "k": "10"}, "def"], {
  8. "x":"abc"}, {
  9. "y":"bcd"}]', 'one', 'abc') |
  10. +--------------------------------------------------------------------------------------+
  11. | "$[0]" |
  12. +--------------------------------------------------------------------------------------+
  13. 1 row in set (0.01 sec)
  14. mysql> select json_search('["abc", [{
  15. "k": "10"}, "def"], {
  16. "x":"abc"}, {
  17. "y":"bcd"}]', 'all', 'abc');
  18. +--------------------------------------------------------------------------------------+
  19. | json_search('["abc", [{
  20. "k": "10"}, "def"], {
  21. "x":"abc"}, {
  22. "y":"bcd"}]', 'all', 'abc') |
  23. +--------------------------------------------------------------------------------------+
  24. | ["$[0]", "$[2].x"] |
  25. +--------------------------------------------------------------------------------------+
  26. 1 row in set (0.00 sec)

json_set往json中插入元素
存在则覆盖,不存在则新增。

  1. mysql> select json_set('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}', "$.a", "aaa", "$.e", "eee");
  4. +-------------------------------------------------------------------------+
  5. | json_set('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}', "$.a", "aaa", "$.e", "eee") |
  8. +-------------------------------------------------------------------------+
  9. | {
  10. "a": "aaa", "b": 2, "c": {
  11. "d": 4}, "e": "eee"} |
  12. +-------------------------------------------------------------------------+
  13. 1 row in set (0.00 sec)

json_storage_size查看json存储占用的空间大小

  1. mysql> select json_storage_size('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +------------------------------------------------------+
  5. | json_storage_size('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +------------------------------------------------------+
  9. | 41 |
  10. +------------------------------------------------------+
  11. 1 row in set (0.00 sec)

json_type查询json的类型

  1. mysql> select json_type('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +----------------------------------------------+
  5. | json_type('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +----------------------------------------------+
  9. | OBJECT |
  10. +----------------------------------------------+
  11. 1 row in set (0.01 sec)

json_valid判断json是否是有效的

  1. mysql> select json_valid('{
  2. "a": 1, "b": 2, "c": {
  3. "d": 4}}');
  4. +-----------------------------------------------+
  5. | json_valid('{
  6. "a": 1, "b": 2, "c": {
  7. "d": 4}}') |
  8. +-----------------------------------------------+
  9. | 1 |
  10. +-----------------------------------------------+
  11. 1 row in set (0.00 sec)

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

  1. mysql> create table test_json_index(id int primary key auto_increment, data json, gen_col varchar(10) generated always as (json_extract(data, '$.name')));
  2. mysql> insert into test_json_index(data) values('{
  3. "name":"morris","age":18,"address":"china"}');
  4. mysql> insert into test_json_index(data) values('{
  5. "name":"tom","age":16,"mail":"tomcat@google.com"}');
  6. mysql> select * from test_json_index;
  7. +----+---------------------------------------------------------+----------+
  8. | id | data | gen_col |
  9. +----+---------------------------------------------------------+----------+
  10. | 1 | {
  11. "age": 18, "name": "morris", "address": "china"} | "morris" |
  12. | 2 | {
  13. "age": 16, "mail": "tomcat@google.com", "name": "tom"} | "tom" |
  14. +----+---------------------------------------------------------+----------+
  15. mysql> select * from test_json_index where gen_col='morris'; -- 查不到数据
  16. mysql> select * from test_json_index where gen_col='"morris"';
  17. +----+---------------------------------------------------+----------+
  18. | id | data | gen_col |
  19. +----+---------------------------------------------------+----------+
  20. | 1 | {
  21. "age": 18, "name": "morris", "address": "china"} | "morris" |
  22. +----+---------------------------------------------------+----------+

要想在查询时不加引号,可以在加索引时使用json_unquote去除引号。

  1. mysql> create table test_json_index2(id int primary key auto_increment, data json, gen_col varchar(10) generated always as (json_unquote(json_extract(data, '$.name'))));
  2. Query OK, 0 rows affected (0.08 sec)
  3. mysql> create table test_json_index3(id int primary key auto_increment, data json, gen_col varchar(10) generated always as (JSON_UNQUOTE(data->'$.name')));
  4. Query OK, 0 rows affected (0.08 sec)
  5. mysql> create table test_json_index4(id int primary key auto_increment, data json, gen_col varchar(10) generated always as (data->>'$.name'));
  6. Query OK, 0 rows affected (0.05 sec)

发表评论

表情:
评论列表 (有 0 条评论,90人围观)

还没有评论,来说两句吧...

相关阅读