mysql> CREATE TABLE `json_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `info` json NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> select * from json_table ; +----+------------------------------+ | id | info | +----+------------------------------+ | 1 | {"age": 24, "name": "lucy"} | | 2 | {"age": 20, "name": "lili"} | | 3 | {"age": 25, "name": "curry"} | +----+------------------------------+ 3 rows in set (0.00 sec)
Creating JSON Values
MySQL裏的json分爲json array和json object。python
-
JSON_TYPE():查看字段類型mysql
-
JSON_ARRAY():返回json數組sql
-
JSON_OBJECT():返回json對象json
-
JSON_MERGE():合併多個json文檔數組
舉個栗子:this
#查看類型 mysql> select id, json_extract(info, '$.name') as name , json_type(json_extract(info, '$.name')) as type from json_table where id=3 ; +----+---------+--------+ | id | name | type | +----+---------+--------+ | 3 | "curry" | STRING | +----+---------+--------+ 1 row in set (0.00 sec) #生成一個json數據組 mysql> select json_array('aaa', 'bbb', 'ddd') as array; +-----------------------+ | array | +-----------------------+ | ["aaa", "bbb", "ddd"] | +-----------------------+ 1 row in set (0.00 sec) #生成一個json對象 mysql> select json_object('aaa', 1, 'bbb', 2, 'ddd', 3) as array; +--------------------------------+ | array | +--------------------------------+ | {"aaa": 1, "bbb": 2, "ddd": 3} | +--------------------------------+ 1 row in set (0.00 sec) #將多個json文檔合併 mysql> select json_merge(json_array('aaa', 'bbb', 'ddd'), json_object('aaa', 1, 'bbb', 2, 'ddd', 3)) as json ; +-------------------------------------------------------+ | json | +-------------------------------------------------------+ | ["aaa", "bbb", "ddd", {"aaa": 1, "bbb": 2, "ddd": 3}] | +-------------------------------------------------------+ 1 row in set, 1 warning (0.00 sec)
JSON查詢
MySQL裏的json分爲json array和json object 對於json array,在索引數據時用從0開始的下標進行索引,$表示整個json對象,例如:$[0]、$[1] 對於json object,在索引數據時用key進行索引,含有特殊字符的key要用""括起來,好比$."my name")spa
-
提取json字段:json列->'$.鍵' 或 JSON_EXTRACT(json列 , '$.鍵')scala
-
去掉json字段雙引號:JSON_UNQOUTE() 或者 json列->>'$.鍵'rest
提取JSON 字段的表達式能夠用於SELECT查詢列表 ,WHERE/HAVING , ORDER/GROUP BY語句中,JSON 中的元素搜索也是嚴格區分變量類型code
json不一樣於字符串,不能看成字符串直接作比較,經過**CAST()**將字符串轉換成JSON形式,再進行比較,後面舉慄
舉個栗子:
json列->'$.鍵' 查詢:
mysql> select id, info->'$.name' as name from json_table ; +----+---------+ | id | name | +----+---------+ | 1 | "lucy" | | 2 | "lili" | | 3 | "curry" | +----+---------+ 3 rows in set (0.00 sec) mysql> select id, info->'$.name' as name from json_table where info->'$.age' >=24; +----+---------+ | id | name | +----+---------+ | 1 | "lucy" | | 3 | "curry" | +----+---------+ 2 rows in set (0.00 sec) ##複雜狀況下的查詢,例如 mysql> select info from json_table where id=3; +----------------------------------------------------------------+ | info | +----------------------------------------------------------------+ | ["abc", {"xxx": [123, 456], "my key": "my value"}, [666, 100]] | +----------------------------------------------------------------+ 1 row in set (0.00 sec) ## 查詢json array的某個值 mysql> select info->'$[0]' from json_table where id=3 ; +---------------+ | info->'$[0]' | +---------------+ | "abc" | +---------------+ 1 row in set (0.00 sec) ## 查詢json array中的的json object mysql> select info->'$[1]."my key"' from json_table where id=3 ; +--------------------------+ | info->'$[1]."my key"' | +--------------------------+ | "my value" | +--------------------------+ 1 row in set (0.00 sec)
**JSON_EXTRACT(json列 , '$.鍵')**查詢:
mysql> select id, json_extract(info, '$.name') as name from json_table ; +----+---------+ | id | name | +----+---------+ | 1 | "lucy" | | 2 | "lili" | | 3 | "curry" | +----+---------+ 3 rows in set (0.05 sec) mysql> select id, json_extract(info, '$.name') as name from json_table where json_extract(info, '$.age') >= 24; +----+---------+ | id | name | +----+---------+ | 1 | "lucy" | | 3 | "curry" | +----+---------+ 2 rows in set (0.00 sec)
**JSON_UNQOUTE()**方法舉慄:
mysql> select id, json_unquote(json_extract(info, '$.name')) as name from json_table ; +----+-------+ | id | name | +----+-------+ | 1 | lucy | | 2 | lili | | 3 | curry | +----+-------+ 3 rows in set (0.00 sec) mysql> select id, info->>'$.name' as name from json_table ; +----+-------+ | id | name | +----+-------+ | 1 | lucy | | 2 | lili | | 3 | curry | +----+-------+ 3 rows in set (0.00 sec)
JSON字段與字符串比較舉慄:
mysql> select * from json_table where info = '{"age": 25, "name": "curry"}'; Empty set (0.00 sec) mysql> select * from json_table where info = cast('{"age": 25, "name": "curry"}' as JSON); +----+------------------------------+ | id | info | +----+------------------------------+ | 3 | {"age": 25, "name": "curry"} | +----+------------------------------+ 1 row in set (0.00 sec)
###JSON的索引
如今MySQL不支持對JSON列進行索引,官網文檔的說明是:
JSON columns cannot be indexed. You can work around this restriction by creating an index on a generated column that extracts a scalar value from the JSON column.
雖然不支持直接在JSON列上建索引,但MySQL規定,能夠首先使用路徑表達式對JSON文檔中的標量值創建虛擬列,而後在虛擬列上創建索引。這樣用戶能夠使用表達式對本身感興趣的鍵值創建索引。
慄如,建立索引:
mysql> alter table json_table add name varchar(20) generated always as (info->'$.name') virtual ; Query OK, 0 rows affected (0.35 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> select * from json_table ; +----+------------------------------+---------+ | id | info | name | +----+------------------------------+---------+ | 1 | {"age": 24, "name": "lucy"} | "lucy" | | 2 | {"age": 20, "name": "lili"} | "lili" | | 3 | {"age": 25, "name": "curry"} | "curry" | | 4 | {"age": 24, "name": "tom"} | "tom" | | 5 | {"age": 24, "name": "jurry"} | "jurry" | | 6 | {"age": 30, "name": "tmry"} | "tmry" | +----+------------------------------+---------+ 6 rows in set (0.00 sec) mysql> select * from json_table where name=""tom""; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'tom""' at line 1 mysql> select * from json_table where name="\"tom\""; +----+----------------------------+-------+ | id | info | name | +----+----------------------------+-------+ | 4 | {"age": 24, "name": "tom"} | "tom" | +----+----------------------------+-------+ 1 row in set (0.00 sec) mysql> alter table json_table add index name_idx(name) ; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table json_table \G *************************** 1. row *************************** Table: json_table Create Table: CREATE TABLE `json_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `info` json NOT NULL, `name` varchar(20) GENERATED ALWAYS AS (json_extract(`info`,'$.name')) VIRTUAL, PRIMARY KEY (`id`), KEY `name_idx` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> alter table json_table rename index name_idx to idx_name ; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table json_table \G *************************** 1. row *************************** Table: json_table Create Table: CREATE TABLE `json_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `info` json NOT NULL, `name` varchar(20) GENERATED ALWAYS AS (json_extract(`info`,'$.name')) VIRTUAL, PRIMARY KEY (`id`), KEY `idx_name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
修改
JSON_INSERT() 插入新字段,對於已存在的字段沒法修改
#插入新字段 mysql> update json_table set info=json_insert(info, '$.sex', 'M'); Query OK, 6 rows affected (0.30 sec) Rows matched: 6 Changed: 6 Warnings: 0 mysql> select * from json_table ; +----+-----------------------------------------------------------+ | id | info | +----+-----------------------------------------------------------+ | 1 | {"age": 24, "sex": "M", "name": "lucy"} | | 2 | {"age": 20, "sex": "M", "name": "lili"} | | 3 | {"age": 25, "sex": "M", "name": "curry"} | | 4 | {"age": 24, "sex": "M", "name": "tom"} | | 5 | {"age": 24, "sex": "M", "name": "jurry"} | | 6 | {"age": 30, "sex": "M", "name": "tmry"} | +----+-----------------------------------------------------------+ 6 rows in set (0.00 sec) #對於已存在的字段沒法修改 mysql> update json_table set info=json_insert(info, '$.name', 'LUCY') where id=1; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 mysql> select * from json_table where id=1 ; +----+-----------------------------------------------------------+ | id | info | +----+-----------------------------------------------------------+ | 1 | {"age": 24, "sex": "M", "name": "lucy"} | +----+-----------------------------------------------------------+ 6 rows in set (0.00 sec)
JSON_SET() 插入新值字段,並覆蓋已經存在字段的值
#覆蓋已經存在字段的值 mysql> update json_table set info=json_set(info, '$.name', 'LUCY') where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from json_table where id=1; +----+-----------------------------------------------------------+ | id | info | +----+-----------------------------------------------------------+ | 1 | {"age": 24, "sex": "M", "name": "LUCY"} | +----+-----------------------------------------------------------+ 1 row in set (0.00 sec) #插入新值字段 mysql> update json_table set info=json_set(info, '$.class', 'python') where id=2; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from json_table where id=2; +----+------------------------------------------------------------+ | id | info | +----+------------------------------------------------------------+ | 2 | {"age": 20, "sex": "M", "name": "lili", "class": "python"} | +----+------------------------------------------------------------+ 1 row in set (0.00 sec)
JSON_REPLACE() 只替換存在的字段
mysql> update json_table set info=json_replace(info, '$.sex', 'W') where id=2; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from json_table where id = 2 ; +----+------------------------------------------------------------+ | id | info | +----+------------------------------------------------------------+ | 2 | {"age": 20, "sex": "W", "name": "lili", "class": "python"} | +----+------------------------------------------------------------+ 1 row in set (0.00 sec)
JSON_REMOVE() 刪除 JSON 元素
mysql> update json_table set info=json_remove(info, '$.class') where id=2 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from json_table where id = 2 ; +----+-----------------------------------------+ | id | info | +----+-----------------------------------------+ | 2 | {"age": 20, "sex": "W", "name": "lili"} | +----+-----------------------------------------+ 1 row in set (0.00 sec)