The JSON Data Type
存儲JSON文檔所需的空間與LONGBLOB或LONGTEXT大致相同府框;存儲在JSON列中的任何JSON文檔的大小都限制為max_allowed_packet系統(tǒng)變量的值±蚶迹可以使用JSON_STORAGE_SIZE( )函數(shù)獲取存儲JSON文檔所需的空間量笼踩。
創(chuàng)建JSON
- JSON數(shù)組包含一組由逗號分隔的值,并且包含在[ ]中
["ade", 12, null, true, false]
- JSON對象包含由逗號分隔的鍵值對,并包含在{ }中郁惜,JSON對象中的鍵必須是字符串或者時間日期
{"k1": "value", "k2": 2}
- JSON數(shù)組和對象都運(yùn)行嵌套
[99, [78, "e"], {"k1": 1, "k2": "a"}, "de"]
{"k1": 1, "k2": [10, "s"]}
常用函數(shù)
- JSON_TYPE()函數(shù)需要JSON參數(shù)并嘗試將其解析為JSON值水评。 如果值有效猩系,則返回值的JSON類型,否則產(chǎn)生錯誤:
mysql> SELECT JSON_TYPE('["a", "b", 1]');
+----------------------------+
| JSON_TYPE('["a", "b", 1]') |
+----------------------------+
| ARRAY |
+----------------------------+
mysql> SELECT JSON_TYPE('"hello"');
+----------------------+
| JSON_TYPE('"hello"') |
+----------------------+
| STRING |
+----------------------+
mysql> SELECT JSON_TYPE('hello');
ERROR 3146 (22032): Invalid data type for JSON data in argument 1
to function json_type; a JSON string or JSON type is required.
- JSON_ARRAY()接受一個(可能是空的)值列表中燥,并返回包含這些值的JSON數(shù)組:
mysql> SELECT JSON_ARRAY('a', 1, NOW());
+----------------------------------------+
| JSON_ARRAY('a', 1, NOW()) |
+----------------------------------------+
| ["a", 1, "2015-07-27 09:43:47.000000"] |
+----------------------------------------+
- JSON_OBJECT()獲取一個(可能為空)鍵值對列表寇甸,并返回包含這些對的JSON對象:
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc');
+---------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc') |
+---------------------------------------+
| {"key1": 1, "key2": "abc"} |
+---------------------------------------+
- JSON_MERGE_PRESERVE()接受兩個或多個JSON文檔并返回組合結(jié)果:
mysql> SELECT JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}');
+-----------------------------------------------------+
| JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}') |
+-----------------------------------------------------+
| ["a", 1, {"key": "value"}] |
+-----------------------------------------------------+
1 row in set (0.00 sec)
- 區(qū)分大小寫也適用于JSON null,true和false文字疗涉,它們必須始終以小寫形式寫入:
- 使用雙反斜杠可防止MySQL執(zhí)行轉(zhuǎn)義序列處理拿霉,而是使其將字符串文字傳遞給存儲引擎進(jìn)行處理。 以剛才顯示的方式插入JSON對象后咱扣,您可以通過執(zhí)行簡單的SELECT看到反斜杠存在于JSON列值中绽淘,如下所示:
- 要使用吉祥物作為鍵來查找這個特定句子,可以使用column-path操作符 - >闹伪,如下所示:
合并數(shù)組
- MySQL 8.0.3(及更高版本)支持兩種合并算法沪铭,由函數(shù)JSON_MERGE_PRESERVE()和JSON_MERGE_PATCH()實現(xiàn)壮池。 它們處理重復(fù)鍵的方式不同:JSON_MERGE_PRESERVE()保留重復(fù)鍵的值,而JSON_MERGE_PATCH()丟棄除最后一個值之外的所有鍵杀怠。 接下來的幾段將解釋這兩個函數(shù)中的每一個如何處理JSON文檔的不同組合(即對象和數(shù)組)的合并椰憋。
- 合并數(shù)組。 在組合多個數(shù)組的上下文中赔退,數(shù)組合并為單個數(shù)組橙依。 JSON_MERGE_PRESERVE()通過將稍后命名的數(shù)組連接到第一個數(shù)組的末尾來完成此操作。 JSON_MERGE_PATCH()將每個參數(shù)視為由單個元素組成的數(shù)組(因此將0作為其索引)离钝,然后應(yīng)用“l(fā)ast duplicate key wins”邏輯以僅選擇最后一個參數(shù)票编。 您可以比較此查詢顯示的結(jié)果:
mysql> SELECT
-> JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Preserve,
-> JSON_MERGE_PATCH('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2, "a", "b", "c", true, false]
Patch: [true, false]
- 合并時的多個對象生成單個對象。 JSON_MERGE_PRESERVE()通過組合數(shù)組中該鍵的所有唯一值來處理具有相同鍵的多個對象; 然后將此數(shù)組用作結(jié)果中該鍵的值卵渴。 JSON_MERGE_PATCH()從左到右丟棄找到重復(fù)鍵的值慧域,以便結(jié)果僅包含該鍵的最后一個值。 以下查詢說明了重復(fù)鍵a的結(jié)果差異:
-> JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,
-> JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch\G
*************************** 1. row ***************************
Preserve: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3}
Patch: {"a": 4, "b": 2, "c": 5, "d": 3}
搜索和修改JSON值
使用JSON路徑表達(dá)式選擇JSON文檔中的值浪读。
- 路徑表達(dá)式對于提取JSON文檔的一部分或修改JSON文檔的函數(shù)很有用昔榴,以指定該文檔中的操作位置。 例如碘橘,以下查詢從JSON文檔中提取名稱為key的成員的值:
mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan" |
+---------------------------------------------------------+
-
某些函數(shù)采用現(xiàn)有的JSON文檔互订,以某種方式對其進(jìn)行修改,并返回生成的修改后的文檔痘拆。 路徑表達(dá)式指示文檔中的更改位置仰禽。 例如,JSON_SET()纺蛆,JSON_INSERT()和JSON_REPLACE()函數(shù)各自采用JSON文檔吐葵,以及一個或多個路徑值對,這些路徑值對描述了修改文檔的位置和要使用的值桥氏。 這些函數(shù)在處理文檔中的現(xiàn)有值和不存在值方面有所不同温峭。
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
- JSON_SET()替換存在的路徑的值,并為不存在的路徑添加值:
mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2); +--------------------------------------------+ | JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) | +--------------------------------------------+ | ["a", {"b": [1, false]}, [10, 20, 2]] | +--------------------------------------------+
- JSON_INSERT()添加新值但不替換現(xiàn)有值:
mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2); +-----------------------------------------------+ | JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) | +-----------------------------------------------+ | ["a", {"b": [true, false]}, [10, 20, 2]] | +-----------------------------------------------+
- JSON_REPLACE()替換現(xiàn)有值并忽略新值:
mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2); +------------------------------------------------+ | JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) | +------------------------------------------------+ | ["a", {"b": [1, false]}, [10, 20]] | +------------------------------------------------+
- JSON_REMOVE()接受一個JSON文檔和一個或多個指定要從文檔中刪除的值的路徑字支。 返回值是原始文檔減去文檔中存在的路徑選擇的值:
mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]'); +---------------------------------------------------+ | JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') | +---------------------------------------------------+ | ["a", {"b": [true]}] | +---------------------------------------------------+