MySQL數據類型 - JSON數據類型 (2)

JSON值的規範化、合併和自動包裝html

當一個字符串被解析並發現是一個有效的JSON文檔時,它也會被規範化。這意味着,具備與稍後在文檔中找到的鍵(從左到右)重複的鍵的成員將被丟棄。JSON_OBJECT()調用生成的對象值只包含第二個key1元素,由於該鍵名在以前值中出現過,以下所示:mysql

MySQL數據類型 - JSON數據類型 (2)

在JSON列中插入值時也會執行規範化,以下所示:算法

MySQL數據類型 - JSON數據類型 (2)
這種"最後一次重複的鍵獲勝"的行爲是由RFC 7159建議的,而且已由大多數JavaScript解析器實現。(Bug #86866, Bug #26369555)sql

在MySQL 8.0.3以前的版本中,與文檔中先前找到的key重複的key成員將被丟棄。如下JSON_OBJECT()調用生成的對象值不包括第二個key1元素,由於該鍵名在前面出現過:
MySQL數據類型 - JSON數據類型 (2)json

在MySQL 8.0.3以前,在向JSON列中插入值時,也會執行"第一個重複鍵獲勝"的規範化。數組

MySQL數據類型 - JSON數據類型 (2)

MySQL還會丟棄原始JSON文檔中鍵、值或元素之間的多餘空格,並在顯示時在每一個逗號(,)或冒號(:)後保留(或在必要時插入)一個空格。這樣作是爲了提升可讀性。併發

產生JSON值的MySQL函數老是返回規範化的值。ide

爲了提升查找效率,MySQL還對JSON對象的鍵進行排序。應該意識到,此排序的結果可能會發生更改,而且不能保證在不一樣版本之間保持一致。函數

合併JSON值spa

MySQL8.0.3(及更高版本)支持兩種合併算法,由函數JSON_MERGE_PRESERVE()和JSON_MERGE_PATCH()實現。它們在處理重複鍵的方式上有所不一樣:JSON_MERGE_PRESERVE()保留重複鍵的值,而JSON_MERGE_PATCH()將丟棄除最後一個值以外的全部值。接下來的幾段將解釋這兩個函數如何處理JSON文檔的不一樣組合(即對象和數組)的合併。

注意

JSON_MERGE_PRESERVE()與早期版本的MySQL(在MySQL 8.0.3中重命名)中的JSON_MERGE()函數相同。在MySQL8.0中,JSON_MERGE()仍然以JSON_MERGE_PRESERVE()別名被支持,但已棄用,並可能在未來的版本中刪除。

合併數組。在組合多個數組的上下文中,數組被合併成一個。JSON_MERGE_PRESERVE()經過將後面說起的數組鏈接到第一個數組的末尾來實現這一點。JSON_MERGE_PATCH()將每一個參數視爲一個由單個元素組成的數組(所以其索引爲0),而後應用"最後一個重複鍵獲勝"邏輯來僅選擇最後一個參數。您能夠比較此查詢顯示的結果:
MySQL數據類型 - JSON數據類型 (2)

多個對象合併後生成一個對象。JSON_MERGE_PRESERVE()把數組中具備相同鍵的對象各惟一值合併;而後將該數組用做結果中該鍵的值。JSON_MERGE_PATCH()從左到右丟棄找到重複鍵的值,這樣結果只包含該鍵的最後一個值。如下查詢說明了重複鍵a的結果差別:
MySQL數據類型 - JSON數據類型 (2)

在須要數組值的上下文中使用非數組值是會自動包裝的:該值由[和]字符包圍以將其轉換爲數組。在下面的語句中,每一個參數都自動包裝爲一個數組([1],[2])。而後將這些值合併生成一個結果數組;與前兩種狀況同樣,JSON_MERGE_PRESERVE()組合具備相同鍵的值,而JSON_MERGE_PATCH()將丟棄除最後一個外的全部重複鍵的值,以下所示:
MySQL數據類型 - JSON數據類型 (2)

數組和對象值的合併是經過將對象自動包裝爲一個數組,並經過合併值來合併數組,或者根據"最後的重複鍵獲勝"原則(分別對應選擇的合併函數是JSON_MERGE_PRESERVE()或JSON_MERGE_PATCH())合併數組,如本例所示:
MySQL數據類型 - JSON數據類型 (2)

搜索和修改JSON值

JSON路徑表達式在JSON文檔中選擇一個值。

路徑表達式指定操做文檔位置,對於提取或修改JSON文檔內容的函數很是有用。例如,如下查詢從JSON文檔中提取具備name鍵的成員的值:
MySQL數據類型 - JSON數據類型 (2)

路徑語法使用前導的$字符來表示處理中的JSON文檔,後面能夠跟選擇器(可選),這些選擇器依次指示文檔中更具體的部分:

●一個句點後跟一個鍵名,用給定的鍵命名對象中的成員。若是不帶引號的鍵名稱在路徑表達式中不合法(例如,若是它包含空格),則必須用在雙引號包含指定鍵名稱。

● [N]附加到選擇數組的路徑後,表示在數組中位置N處的值。數組位置是以零開頭的整數。若是路徑未選擇數組值,則路徑[0]的計算結果與路徑相同:

MySQL數據類型 - JSON數據類型 (2)

●[M to N]指定數組值的子集或範圍,從位置M處的值開始,到位置N處的值結束。

支持用last做爲最右邊數組元素的索引的同義詞。還支持數組元素的相對尋址。若是path沒有選擇數組值,path[last]的計算結果與path相同,如本節後面部分所示。

●路徑能夠包含*或**通配符:

■ .[*]計算JSON對象中全部成員的值。

■ [*]計算JSON數組中全部元素的值。

■ prefix**suffix計算以prefix開頭、以suffix結束的全部路徑。

● 文檔中不存在的路徑(計算結果爲不存在的數據)計算結果爲NULL。

讓$引用包含三個元素的JSON數組:
MySQL數據類型 - JSON數據類型 (2)

而後:

● $[0]的計算結果爲3。

● $[1]的計算結果爲{"a": [5, 6], "b": 10}。

● $[2]的計算結果爲[99, 100]。

● $[3]的計算結果爲NULL(它引用第四個數組元素,它不存在)。

因爲$[1]和$[2]的計算結果爲非標量值,所以能夠用更具體的路徑表達式對它們選擇嵌套的值。示例:

●$[1].a的計算結果爲[5, 6]。

●$[1].a[1]的計算結果爲6。

●$[1].b的值爲10。

●$[2][0]的計算結果爲99。

如前所述,若是未加引號的鍵名稱在路徑表達式中不合法,則必須用引號將鍵引發。讓$來引用此值:
MySQL數據類型 - JSON數據類型 (2)

兩個鍵都包含空格,必須用引號引用:

●$."a fish"的計算結果是shark。

●$."a bird"的計算結果是sparrow。

使用通配符的路徑計算的數組能夠包含多個值:

MySQL數據類型 - JSON數據類型 (2)

在如下示例中,路徑$**.b計算爲多個路徑($.a.b和$.c.b),並生成匹配路徑值的數組:

MySQL數據類型 - JSON數據類型 (2)

JSON數組區間。能夠使用帶有to關鍵字的區間來指定JSON數組的子集。例如,$[1 to 3]包括數組的第2、第三和第四個元素,以下所示:

MySQL數據類型 - JSON數據類型 (2)

語法是 M to N,其中M和N分別是JSON數組中一系列元素的第一個和最後一個索引。N必須大於M;M必須大於或等於0。數組元素以0開頭編制索引。

能夠在支持通配符的上下文中使用區間。

官方文檔地址:
https://dev.mysql.com/doc/refman/8.0/en/json.html

相關文章
相關標籤/搜索