自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊MySQL 8.0中的Json增強(qiáng)

數(shù)據(jù)庫 MySQL
現(xiàn)在很多應(yīng)用環(huán)境中都能看到JSON靈活的影子。各階段數(shù)據(jù)層次的遞歸層次,能很好的分辨。一直對(duì)MySQL的JSON很期待的,最近才有時(shí)間研究一下。

[[403533]]

本文轉(zhuǎn)載自微信公眾號(hào)「數(shù)據(jù)和云」,作者崔虎龍。轉(zhuǎn)載本文請(qǐng)聯(lián)系數(shù)據(jù)和云公眾號(hào)。

現(xiàn)在很多應(yīng)用環(huán)境中都能看到JSON靈活的影子。各階段數(shù)據(jù)層次的遞歸層次,能很好的分辨。一直對(duì)MySQL的JSON很期待的,最近才有時(shí)間研究一下。

JSON了解

JSON就是一串字符串,只不過元素會(huì)使用特定的符號(hào)標(biāo)注。比如:

  • {} 雙括號(hào)表示對(duì)象
  • [] 中括號(hào)表示數(shù)組
  • “” 雙引號(hào)內(nèi)是屬性或值
  • : 冒號(hào)表示后者是前者的值

關(guān)系型數(shù)據(jù)庫實(shí)現(xiàn)JSON難度在于,關(guān)系型數(shù)據(jù)庫需要定義數(shù)據(jù)庫和表結(jié)構(gòu)。為了應(yīng)對(duì)這一點(diǎn),從MySQL 5.7開始,MySQL支持了JavaScript對(duì)象表示(JavaScriptObject Notation,JSON) 數(shù)據(jù)類型。之前,這類數(shù)據(jù)不是單獨(dú)的數(shù)據(jù)類型,會(huì)被存儲(chǔ)為字符串。新的JSON數(shù)據(jù)類型提供了自動(dòng)驗(yàn)證的JSON文檔以及優(yōu)化的存儲(chǔ)格式。

MySQL里JSON文檔以二進(jìn)制格式存儲(chǔ),它提供以下功能:

  • 自動(dòng)驗(yàn)證存儲(chǔ)在JSON列中的JSON文檔。無效文檔產(chǎn)生錯(cuò)誤。
  • 優(yōu)化的存儲(chǔ)格式。存儲(chǔ)在JSON列中的JSON文檔被轉(zhuǎn)換為允許快速讀取訪問文檔元素的內(nèi)部格式。二進(jìn)制格式存儲(chǔ)的JSON值。
  • 對(duì)文檔元素的快速讀取訪問。當(dāng)服務(wù)器再次讀取JSON文檔時(shí),不需要重新解析文本獲取該值。通過鍵或數(shù)組索引直接查找子對(duì)象或嵌套值,而不需要讀取文檔中的所有值。
  • 存儲(chǔ)JSON文檔所需的空間大致與LONGBLOB或LONGTEXT相同。
  • 存儲(chǔ)在JSON列中的任何JSON文檔的大小都僅限于max_allowed_packet系統(tǒng)變量的值。
  • MySQL 8.0.13之前,JSON列不能有非NULL的默認(rèn)值。

JSON操作

數(shù)據(jù)保存到MySQL,操作方面都提供哪些支持?目前MySQL 8.0版本的的JSON總共支持32個(gè)普通函數(shù)和2個(gè)空間函數(shù):

 

1. 索引:

  • JSON列,像其他二進(jìn)制類型的列一樣,不直接索引;相反,您可以在生成的列上創(chuàng)建索引,從JSON列中提取標(biāo)量值。有關(guān)詳細(xì)示例,請(qǐng)參見為生成的列建立索引以提供JSON列索引。
  • MySQL優(yōu)化器還會(huì)在匹配JSON表達(dá)式的虛擬列上尋找兼容的索引。
  • 在MySQL 8.0.17及以后版本中,InnoDB存儲(chǔ)引擎支持JSON數(shù)組上的多值索引??吹蕉嘀邓饕?/li>
  • MySQL NDB Cluster 8.0支持JSON列和MySQL JSON函數(shù),包括在從JSON列生成的列上創(chuàng)建索引,作為無法索引JSON列的解決方案。每個(gè)NDB表最多支持3個(gè)JSON列。

2.JSON值的比較和排序:

  • JSON值可以使用=、<、<=、>、>=、<>、!=和<=>操作符進(jìn)行比較。
  • JSON值不支持以下比較操作符和函數(shù):

BETWEEN

IN()

GREATEST()

LEAST()

  • 對(duì)于列出的比較操作符和函數(shù),一種變通方法是將JSON值轉(zhuǎn)換為本地MySQL數(shù)值或字符串?dāng)?shù)據(jù)類型,以便它們具有一致的非JSON標(biāo)量類型。就是說轉(zhuǎn)換成需要的MySQL字段繼續(xù)換算,也算是一種折中方案。
  • JSON值的比較分為兩個(gè)級(jí)別。第一級(jí)比較基于比較值的JSON類型。如果類型不同,則僅由哪個(gè)類型優(yōu)先級(jí)更高來決定比較結(jié)果。如果兩個(gè)值具有相同的JSON類型,則使用特定類型的規(guī)則進(jìn)行第二級(jí)比較。

BLOB > BIT > OPAQUE > DATETIME > TIME > DATE > BOOLEAN > ARRAY > OBJECT > STRING > INTEGER, DOUBLE > NULL。

3.JSON和非JSON值之間的轉(zhuǎn)換:

MySQL在JSON值和其他類型值之間轉(zhuǎn)換時(shí)遵循的規(guī)則:

CAST(other type AS JSON)

結(jié)果為JSON類型的NULL值。

  1. mysql>SET @j5 = '{"id":123, "name":"kevin","age":20, "time":"2021-06-01 01:00:00"}'
  2. Query OK, 0 rows affected (0.00 sec) 
  3.  
  4. mysql>SELECT CAST(JSON_EXTRACT(@j5, '$.age'AS UNSIGNED); 
  5. +----------------------------------------------+ 
  6. CAST(JSON_EXTRACT(@j5, '$.age'AS UNSIGNED) | 
  7. +----------------------------------------------+ 
  8. |                                           20 | 
  9. +----------------------------------------------+ 
  10. 1 row in set (0.00 sec) 

4.JSON值聚合:

對(duì)于JSON值的聚合,NULL值和其他數(shù)據(jù)類型一樣被忽略。除MIN()、MAX()和GROUP_CONCAT()外,非NULL值被轉(zhuǎn)換為數(shù)字類型并聚合。對(duì)于數(shù)字標(biāo)量的JSON值,(取決于值)可能會(huì)出現(xiàn)截?cái)嗪途葥p失。

JSON使用索引方式:

MySQL JSON列上無法創(chuàng)建索引,是通過從JSON列中提取標(biāo)量值,創(chuàng)建索引。這樣能更有效的結(jié)合MySQL優(yōu)勢。

  • MySQL優(yōu)化器會(huì)在匹配JSON表達(dá)式的虛擬列上尋找兼容的索引。
  • 在MySQL 8.0.17及以后版本中,InnoDB存儲(chǔ)引擎支持JSON數(shù)組上的多值索引
  • MySQL NDB Cluster 8.0支持JSON列和MySQL JSON函數(shù),包括在從JSON列生成的列上創(chuàng)建索引,作為無法索引JSON列的解決方案。每個(gè)NDB表最多支持3個(gè)JSON列。

1.虛擬列索引:

  1. col_name data_type [GENERATED ALWAYS] AS (expr) 
  2.   [VIRTUAL | STORED] [NOT NULL | NULL
  3.   [UNIQUE [KEY]] [[PRIMARYKEY
  4.   [COMMENT 'string'

VIRTUAL或STORED關(guān)鍵字表示列值是如何存儲(chǔ)的,這對(duì)列的使用影響非常大:

  • VIRTUAL:不存儲(chǔ)列值,但在讀取行時(shí),在任何【BEFORE觸發(fā)器】之后立即計(jì)算列值。虛擬列不占用存儲(chǔ)空間,但暫居內(nèi)存。目前官方里沒有設(shè)置這個(gè)極限。
  • STORED:當(dāng)插入或更新行時(shí),將計(jì)算并存儲(chǔ)列值。存儲(chǔ)的列需要存儲(chǔ)空間,并且可以建立索引。
  • 如果沒有指定關(guān)鍵字,則默認(rèn)為VIRTUAL。
  1. mysql> DROP TABLE IF EXISTS `jemp`; 
  2. mysql> CREATE TABLE  `jemp` ( 
  3.         id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
  4.         c JSON, 
  5.     d JSON, 
  6.         g INT GENERATED ALWAYS AS  (c->"$.id") STORED, 
  7.         INDEX i (g) 
  8.     ); 
  9. Query OK, 0 rows affected (0.02 sec) 
  10. mysql> INSERT INTO jemp (c,d) VALUES  
  11. ('{"id": "1", "name": "Fred"}' , '{"user":"Fred",   "user_id":1, "zipcode":"[14471,14531]"}'), 
  12. ('{"id": "2", "name": "Wilma"}''{"user":"Wilma",  "user_id":2, "zipcode":[24472,24532]}'  ), 
  13. ('{"id": "3", "name": "Jack"}' , '{"user":"Jack", "user_id":3, "zipcode":[34473,34533]}'    ),  
  14. ('{"id": "4", "name": "Betty"}''{"user":"Betty",  "user_id":4, "zipcode":[44474,44534]}'  ); 
  15.  
  16. Query OK, 4 rows affected (0.02 sec) 
  17. Records: 4  Duplicates: 0  Warnings: 0 
  18.  
  19. mysql> EXPLAIN SELECT c->>"$.name" AS name  FROM jemp WHERE g > 2\G; 
  20. *************************** 1. row *************************** 
  21.            id: 1 
  22.   select_type: SIMPLE 
  23.         table: jemp 
  24.    partitions: NULL 
  25.          type: range 
  26. possible_keys: i 
  27.           key: i 
  28.       key_len: 5 
  29.           ref: NULL 
  30.          rows: 2 
  31.      filtered: 100.00 
  32.         Extra: Using where 
  33. 1 row in set, 1 warning (0.00 sec) 
  1. ERROR: 
  2. No query specified 
  3.  
  4. mysql> SHOW WARNINGS\G 
  5. *************************** 1. row *************************** 
  6.  Level: Note 
  7.    Code: 1003 
  8. Message: /* select#1 */ select json_unquote(json_extract(`db1`.`jemp`.`c`,'$.name')) AS `namefrom `db1`.`jemp` where (`db1`.`jemp`.`g` > 2) 
  9. 1 row in set (0.00 sec) 

2.使用多值索引

直接接口:MEMBER OF(),JSON_CONTAINS(),JSON_OVERLAPS()

  1. mysql> ALTER TABLE jemp ADD INDEX zips( (CAST(d->'$.zipcode' AS UNSIGNED ARRAY)) ); 
  2.  
  3. #MEMBER  OF 
  4. mysql> EXPLAIN  SELECT * FROM jemp    WHERE  24472 MEMBER  OF(d->'$.zipcode')\G 
  5. *************************** 1. row *************************** 
  6.            id: 1 
  7.   select_type: SIMPLE 
  8.         table: jemp 
  9.    partitions: NULL 
  10.          type: ref 
  11. possible_keys: zips 
  12.           key: zips 
  13.       key_len: 9 
  14.           ref: const 
  15.         rows: 1 
  16.      filtered: 100.00 
  17.         Extra: Using where 
  18. 1 row in set, 1 warning (0.00 sec) 
  19.  
  20. #JSON_CONTAINS 
  21. mysql> EXPLAIN SELECT * FROM jemp   WHERE JSON_CONTAINS(d->'$.zipcode'CAST('[14471,14531]' AS JSON))\G; 
  22. *************************** 1. row *************************** 
  23.            id: 1 
  24.   select_type: SIMPLE 
  25.         table: jemp 
  26.    partitions: NULL 
  27.          type: range 
  28. possible_keys: zips 
  29.           key: zips 
  30.       key_len: 9 
  31.           ref: NULL 
  32.          rows: 2 
  33.      filtered: 100.00 
  34.         Extra: Using where 
  35. 1 row in set, 1 warning (0.00 sec) 
  36.  
  37. #JSON_OVERLAPS 
  38. mysql> EXPLAIN SELECT * FROM jemp   WHERE JSON_OVERLAPS(d->'$.zipcode'CAST('[44474,94582]' AS JSON))\G; 
  39. *************************** 1. row *************************** 
  40.            id: 1 
  41.   select_type: SIMPLE 
  42.         table: jemp 
  43.    partitions: NULL 
  44.          type: range 
  45. possible_keys: zips 
  46.           key: zips 
  47.       key_len: 9 
  48.           ref: NULL 
  49.          rows: 2 
  50.      filtered: 100.00 
  51.         Extra: Using where 
  52. 1 row in set, 1 warning (0.00 sec) 

從上面例子里,數(shù)據(jù)的查詢還是基于MySQL B+tree上,JSON只是一種數(shù)據(jù)保存的機(jī)制。通過對(duì)虛擬列方式,提供快速的訪問,非常好的解決了JSON支持問題。

總結(jié)

  • MySQL里JSON的結(jié)合非常實(shí)用,虛擬列索引解決了查詢的性能問題。
  • JSON大小確實(shí)個(gè)硬性問題,謹(jǐn)慎使用(空間大致與LONGBLOB或LONGTEXT相同,文檔的大小都僅限于max_allowed_packet系統(tǒng)變量的值)。
  • 實(shí)際場景中,只能選擇適中的JSON長度,可以考慮配合大頁使用。

關(guān)于作者

崔虎龍,云和恩墨MySQL技術(shù)顧問,長期服務(wù)于金融、游戲、物流等行業(yè)的數(shù)據(jù)中心,設(shè)計(jì)數(shù)據(jù)存儲(chǔ)架構(gòu),并熟悉數(shù)據(jù)中心運(yùn)營管理的流程及規(guī)范,自動(dòng)化運(yùn)維等。擅長MySQL、Redis、MongoDB數(shù)據(jù)庫高可用設(shè)計(jì)和運(yùn)維故障處理、備份恢復(fù)、升級(jí)遷移、性能優(yōu)化。自學(xué)通過了MySQL OCP 5.6和MySQL OCP 5.7認(rèn)證。2年多開發(fā)經(jīng)驗(yàn),10年數(shù)據(jù)庫運(yùn)維工作經(jīng)驗(yàn),其中專職做MySQL工作8年;曾經(jīng)擔(dān)任過項(xiàng)目經(jīng)理、數(shù)據(jù)庫經(jīng)理、數(shù)據(jù)倉庫架構(gòu)師、MySQL技術(shù)專家、DBA等職務(wù);涉及行業(yè):金融(銀行、理財(cái))、物流、游戲、醫(yī)療、重工業(yè)等。

 

責(zé)任編輯:武曉燕 來源: 數(shù)據(jù)和云
相關(guān)推薦

2022-10-10 08:01:08

MySQL字典表

2021-10-19 10:26:31

MySQL.MySQLJSON

2022-06-05 23:31:28

ClionMySQL數(shù)據(jù)

2021-11-17 08:11:35

MySQL

2023-11-09 11:56:28

MySQL死鎖

2023-03-29 08:13:48

MySQL檢索成本

2021-01-28 14:50:50

微信朋友圏版本

2023-06-12 09:09:19

MySQLDDLNSTANT

2023-12-18 07:32:08

ChatGPTLLMCoT

2021-08-31 07:54:24

SQLDblink查詢

2024-04-26 00:00:00

Rust檢查器代碼

2024-02-26 07:39:16

2023-10-25 14:51:38

MySQL數(shù)據(jù)庫JSON

2022-04-02 10:23:12

MySQL數(shù)據(jù)庫

2023-05-03 21:34:34

MySQL狀態(tài)變量

2022-11-26 08:16:26

2021-03-08 00:11:02

Spring注解開發(fā)

2023-07-28 09:54:14

SQL數(shù)據(jù)Excel

2022-05-11 09:01:54

Swift類型系統(tǒng)幻象類型

2021-10-30 19:56:10

Flutter按鈕 Buttons
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)