MySQL JSON數(shù)據(jù)類(lèi)型如何操作?這里告訴你~
概述
mysql 自 5.7.8 版本開(kāi)始,就支持了 json 結(jié)構(gòu)的數(shù)據(jù)存儲(chǔ)和查詢(xún),這表明了 mysql 也在不斷的學(xué)習(xí)和增加 nosql 數(shù)據(jù)庫(kù)的優(yōu)點(diǎn)。但 mysql 畢竟是關(guān)系型數(shù)據(jù)庫(kù),在處理 json 這種非結(jié)構(gòu)化的數(shù)據(jù)時(shí),還是比較別扭的。
創(chuàng)建一個(gè) JSON 字段的表
首先先創(chuàng)建一個(gè)表,這個(gè)表包含一個(gè) json 格式的字段:
- CREATE TABLE table_name (
- id INT NOT NULL AUTO_INCREMENT,
- json_col JSON,
- PRIMARY KEY(id)
- );
上面的語(yǔ)句,主要注意 json_col 這個(gè)字段,指定的數(shù)據(jù)類(lèi)型是 JSON。
插入一條簡(jiǎn)單的 JSON 數(shù)據(jù)
- INSERT INTO
- table_name (json_col)
- VALUES
- (
- '{"City": "Galle", "Description": "Best damn city in the world"}'
- );
上面這個(gè) SQL 語(yǔ)句,主要注意 VALUES 后面的部分,由于 json 格式的數(shù)據(jù)里,需要有雙引號(hào)來(lái)標(biāo)識(shí)字符串,所以,VALUES 后面的內(nèi)容需要用單引號(hào)包裹。
插入一條復(fù)雜的 JSON 數(shù)據(jù)
- INSERT INTO table(col)
- VALUES(
- '{"opening":"Sicilian","variations":["pelikan","dragon","najdorf"]}'
- );
這地方,我們插入了一個(gè) json 數(shù)組。主要還是注意單引號(hào)和雙引號(hào)的問(wèn)題。
修改 JSON 數(shù)據(jù)
之前的例子中,我們插入了幾條 JSON 數(shù)據(jù),但是如果我們想修改 JSON 數(shù)據(jù)里的某個(gè)內(nèi)容,怎么實(shí)現(xiàn)了?比如我們向 variations 數(shù)組里增加一個(gè)元素,可以這樣:
- UPDATE myjson SET dict=JSON_ARRAY_APPEND(dict,'$.variations','scheveningen') WHERE id = 2;
這個(gè) SQL 語(yǔ)句中,$ 符合代表 JSON 字段,通過(guò). 號(hào)索引到 variations 字段,然后通過(guò) JSON_ARRAY_APPEND 函數(shù)增加一個(gè)元素?,F(xiàn)在我們執(zhí)行查詢(xún)語(yǔ)句:
- SELECT * FROM myjson
得到的結(jié)果是:
- +----+-----------------------------------------------------------------------------------------+
- | id | dict |
- +---+-----------------------------------------------------------------------------------------+
- | 2 | { "opening" : "Sicilian" , "variations" : [ "pelikan" , "dragon" , "najdorf" , "scheveningen" ]} |
- +----+-----------------------------------------------------------------------------------------+
- 1 row in set ( 0.00 sec)
關(guān)于 MySQL 中,JSON 數(shù)據(jù)的獲取方法,參照官方鏈接 JSON Path Syntax
創(chuàng)建索引
MySQL 的 JSON 格式數(shù)據(jù)不能直接創(chuàng)建索引,但是可以變通一下,把要搜索的數(shù)據(jù)單獨(dú)拎出來(lái),單獨(dú)一個(gè)數(shù)據(jù)列,然后在這個(gè)字段上鍵一個(gè)索引。下面是官方的例子:
- mysql> CREATE TABLE jemp (
- -> c JSON,
- -> g INT GENERATED ALWAYS AS (c-> "$.id" ),
- -> INDEX i (g)
- -> );
- Query OK, 0 rows affected ( 0.28 sec)
- mysql> INSERT INTO jemp (c) VALUES
- > ( '{"id": "1", "name": "Fred"}' ), ( '{"id": "2", "name": "Wilma"}' ),
- > ( '{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}' );
- Query OK, 4 rows affected ( 0.04 sec)
- Records : 4 Duplicates: 0 Warnings : 0
- mysql> SELECT c->> "$.name" AS name
- > FROM jemp WHERE g > 2 ;
- +--------+
- | name |
- +--------+
- | Barney |
- | Betty |
- +--------+
- 2 rows in set ( 0.00 sec)
- mysql> EXPLAIN SELECT c->> "$.name" AS name
- > FROM jemp WHERE g > 2 \G
- *************************** 1. row ***************************
- id: 1
- select_type: SIMPLE
- table: jemp
- partitions: NULL
- type: range
- possible_keys: i
- key: i
- key_len: 5
- ref : NULL
- rows: 2
- filtered: 100.00
- Extra: Using where
- 1 row in set , 1 warning ( 0.00 sec)
- mysql> SHOW WARNINGS\G
- *************************** 1. row ***************************
- Level : Note
- Code : 1003
- Message : /* select#1 */ select json_unquote(json_extract( `test` . `jemp` . `c` , '$.name'))
- AS `name` from `test` . `jemp`where ( `test` . `jemp` . `g` > 2 )
- 1 row in set ( 0.00 sec)
這個(gè)例子很簡(jiǎn)單,就是把 JSON 字段里的 id 字段,單獨(dú)拎出來(lái)成字段 g,然后在字段 g 上做索引,查詢(xún)條件也是在字段 g 上。
字符串轉(zhuǎn) JSON 格式
把 json 格式的字符串轉(zhuǎn)換成 MySQL 的 JSON 類(lèi)型:
- SELECT CAST('[1,2,3]' as JSON) ;
- SELECT CAST('{"opening":"Sicilian","variations":["pelikan","dragon","najdorf"]}' as JSON);
所有 MYSQL JSON 函數(shù)
- Name Description
- JSON_APPEND() Append data to JSON document
- JSON_ARRAY() Create JSON array
- JSON_ARRAY_APPEND() Append data to JSON document
- JSON_ARRAY_INSERT() Insert into JSON array-> Return value from JSON column after evaluating path; equivalent to JSON_EXTRACT().
- JSON_CONTAINS() Whether JSON document contains specific object at path
- JSON_CONTAINS_PATH() Whether JSON document contains any data at path
- JSON_DEPTH() Maximum depth of JSON document
- JSON_EXTRACT() Return data from JSON document->> Return value from JSON column after evaluating path and unquoting the result; equivalent to JSON_UNQUOTE(JSON_EXTRACT()).
- JSON_INSERT() Insert data into JSON document
- JSON_KEYS() Array of keys from JSON document
- JSON_LENGTH() Number of elements in JSON document
- JSON_MERGE() Merge JSON documents, preserving duplicate keys. Deprecated synonym for JSON_MERGE_PRESERVE()
- JSON_MERGE_PRESERVE() Merge JSON documents, preserving duplicate keys
- JSON_OBJECT() Create JSON object
- JSON_QUOTE() Quote JSON document
- JSON_REMOVE() Remove data from JSON document
- JSON_REPLACE() Replace values in JSON document
- JSON_SEARCH() Path to value within JSON document
- JSON_SET() Insert data into JSON document
- JSON_TYPE() Type of JSON value
- JSON_UNQUOTE() Unquote JSON value
- JSON_VALID() Whether JSON value is valid