MySQL進(jìn)行JSON復(fù)雜查詢的完全指南
一、JSON對(duì)象全等判斷:當(dāng)強(qiáng)迫癥遇到數(shù)據(jù)結(jié)構(gòu)
1.1 精確匹配(鍵順序敏感)
-- 案例:查找配置完全相同的設(shè)備(鍵順序必須一致) SELECT * FROM device_configs WHERE config_json = '{"resolution": "1080p", "brightness": 80}'; -- 陷阱警告:以下兩個(gè)JSON會(huì)被認(rèn)為不同(鍵順序不同) '{"a":1, "b":2}' vs '{"b":2, "a":1}'
1.2 松散全等判斷(鍵順序無(wú)關(guān))
-- 方法:使用JSON_CONTAINS雙向包含 + 長(zhǎng)度相同 SELECT * FROM device_configs WHERE JSON_CONTAINS(config_json, '{"brightness": 80, "resolution": "1080p"}') AND JSON_CONTAINS('{"brightness": 80, "resolution": "1080p"}', config_json) AND JSON_LENGTH(config_json) = 2; -- 確保沒(méi)有多余字段
二、數(shù)組的“靈魂拷問(wèn)”式查詢
2.1 數(shù)組完全相等(順序敏感)
-- 查找tags數(shù)組嚴(yán)格等于["VIP","北京"]的用戶(順序、數(shù)量、元素完全一致) SELECT * FROM users WHERE tags_json = CAST('["VIP","北京"]' AS JSON);
2.2 數(shù)組包含所有元素(順序無(wú)關(guān))
-- 查找tags包含"VIP"和"北京"的用戶(類似AND條件) SELECT * FROM users WHERE JSON_CONTAINS(tags_json, '"VIP"') AND JSON_CONTAINS(tags_json, '"北京"');
2.3 數(shù)組包含任意元素(類似OR條件)
-- 查找tags包含"VIP"或"北京"的用戶 SELECT * FROM users WHERE JSON_CONTAINS(tags_json, '["VIP"]') OR JSON_CONTAINS(tags_json, '["北京"]');
三、嵌套結(jié)構(gòu)的“掘地三尺”查詢
3.1 多層級(jí)路徑查詢
-- 查找住在"北京朝陽(yáng)區(qū)"的用戶(嵌套對(duì)象查詢) SELECT * FROM users WHERE address_json->>'$.city' = '北京' AND address_json->>'$.district' = '朝陽(yáng)區(qū)';
3.2 通配符搜索所有層級(jí)
-- 查找任意層級(jí)包含"error_code":500的日志(遞歸搜索) SELECT * FROM service_logs WHERE JSON_SEARCH(log_json, 'all', '500', NULL, '$**.error_code') IS NOT NULL;
3.3 深度過(guò)濾數(shù)組對(duì)象
-- 查找訂單中有商品ID=100且數(shù)量>2的訂單(數(shù)組對(duì)象過(guò)濾) SELECT * FROM orders WHERE JSON_EXISTS( items_json, '$[*]?(@.product_id == 100 && @.quantity > 2)' );
四、混合條件綜合查詢
4.1 JSON字段 + 關(guān)系字段聯(lián)合查詢
-- 查找2023年后注冊(cè),且擴(kuò)展信息中device_type="iOS"的用戶 SELECT * FROM users WHERE register_time > '2023-01-01' AND ext_info->>'$.device_type' = 'iOS';
4.2 多JSON字段關(guān)聯(lián)查詢
-- 查找購(gòu)物車總價(jià)>1000且包含"急件"標(biāo)簽的訂單 SELECT * FROM orders WHERE CAST(cart_info->>'$.total_price' AS DECIMAL) > 1000 AND JSON_CONTAINS(tags_json, '"急件"');
4.3 動(dòng)態(tài)條件生成查詢
-- 根據(jù)前端傳入的JSON過(guò)濾條件動(dòng)態(tài)查詢(PHP示例) $filters = '{"status":"pending","price":{"$gt":100}}'; $where = []; foreach(json_decode($filters, true) as $key => $value){ if(is_array($value)){ $where[] = "data_json->>'$.$key' > ".$value['$gt']; }else{ $where[] = "data_json->>'$.$key' = '$value'"; } } $sql = "SELECT * FROM products WHERE ".implode(' AND ', $where);
五、性能優(yōu)化黑科技
5.1 虛擬列 + 索引加速
-- 為常用查詢條件創(chuàng)建虛擬列索引 ALTER TABLE users ADD COLUMN city VARCHAR(20) GENERATED ALWAYS AS (address_json->>'$.city'), ADD INDEX idx_city (city);
5.2 函數(shù)索引(MySQL 8.0+)
-- 直接為JSON路徑表達(dá)式創(chuàng)建索引 CREATE INDEX idx_price ON products ((CAST(data_json->>'$.price' AS DECIMAL)));
5.3 查詢重寫優(yōu)化
-- 原查詢(性能差) SELECT * FROM logs WHERE JSON_EXTRACT(log_data, '$.request.time') > '2023-01-01'; -- 優(yōu)化后(提取時(shí)間到獨(dú)立字段 + 索引) ALTER TABLE logs ADD COLUMN request_time DATETIME GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(log_data, '$.request.time'))); CREATE INDEX idx_request_time ON logs(request_time);
六、經(jīng)典踩坑案例
6.1 隱式類型轉(zhuǎn)換陷阱
-- 錯(cuò)誤:字符串與數(shù)字比較導(dǎo)致索引失效 SELECT * FROM products WHERE data_json->>'$.id' = 100; -- $.id值是字符串"100" -- 正確:顯式類型轉(zhuǎn)換 SELECT * FROM products WHERE CAST(data_json->>'$.id' AS UNSIGNED) = 100;
6.2 通配符濫用災(zāi)難
-- 錯(cuò)誤:左模糊查詢?nèi)頀呙? SELECT * FROM articles WHERE content_json->>'$.text' LIKE '%重要通知%'; -- 正確:使用全文索引或?qū)S盟阉饕妫ㄈ鏓lasticsearch)
6.3 大JSON修改雪崩
-- 錯(cuò)誤:頻繁更新大JSON字段導(dǎo)致IO飆升 UPDATE user_activities SET log_json = JSON_ARRAY_APPEND(log_json, '$', '新事件') WHERE user_id = 1001; -- 正確:拆分成關(guān)系表或分片存儲(chǔ)
七、超硬核面試題
題目:如何高效實(shí)現(xiàn)JSON數(shù)組的交集查詢?
示例:查找tags數(shù)組同時(shí)包含["VIP","北京","90后"]的用戶
參考答案:
-- 方法1:JSON_CONTAINS鏈?zhǔn)秸{(diào)用 SELECT * FROM users WHERE JSON_CONTAINS(tags_json, '"VIP"') AND JSON_CONTAINS(tags_json, '"北京"') AND JSON_CONTAINS(tags_json, '"90后"'); -- 方法2:利用JSON_TABLE展開后統(tǒng)計(jì)(MySQL 8.0+) SELECT user_id FROM users, JSON_TABLE( tags_json, '$[*]' COLUMNS(tag VARCHAR(10) PATH '$') ) AS tags WHERE tag IN ('VIP', '北京', '90后') GROUP BY user_id HAVING COUNT(DISTINCT tag) = 3;
到此這篇關(guān)于MySQL進(jìn)行JSON復(fù)雜查詢的完全指南的文章就介紹到這了,更多相關(guān)MySQL JSON查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql啟動(dòng)提示:錯(cuò)誤2系統(tǒng)找不到指定文件的解決方案
這篇文章主要給大家介紹了mysql啟動(dòng)提示:錯(cuò)誤2系統(tǒng)找不到指定文件的解決方案,文中通過(guò)圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案
在MySQL中用很多類型的自增ID,每個(gè)自增ID都設(shè)置了初始值,一般情況下初始值都是從0開始,然后按照一定的步長(zhǎng)增加(一般是自增 1),下面這篇文章主要給大家介紹了關(guān)于mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案,需要的朋友可以參考下2023-04-04MySQL預(yù)編譯語(yǔ)句過(guò)多告警排查及解決方案
在使用Spring Cloud Alibaba搭建的微服務(wù)架構(gòu)中,項(xiàng)目采用ShardingSphere進(jìn)行分庫(kù)分表,MyBatis-Plus作為持久層,線上環(huán)境突發(fā)大量預(yù)編譯語(yǔ)句過(guò)多的數(shù)據(jù)庫(kù)告警,導(dǎo)致系統(tǒng)性能下降,所以本文給大家介紹了MySQL預(yù)編譯語(yǔ)句過(guò)多告警排查及解決方案,需要的朋友可以參考下2025-01-01MySQL深分頁(yè)問(wèn)題四種方案小結(jié)
在數(shù)據(jù)量大時(shí),深分頁(yè)查詢速度緩慢,主要原因是多次回表查詢,優(yōu)化方法主要介紹了四種,各方法適用于不同場(chǎng)景,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下2024-11-11mysql使用自定義序列實(shí)現(xiàn)row_number功能(步驟詳解)
這篇文章主要介紹了mysql使用自定義序列實(shí)現(xiàn)row_number功能,本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join如期而至
MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join 如期而至,這篇文章帶大家快速瀏覽一下MySQL 8.0.18 穩(wěn)定版的各個(gè)亮點(diǎn),感興趣的小伙伴們可以學(xué)習(xí)參考一下2019-10-10