MySQL進(jìn)行JSON復(fù)雜查詢的完全指南
一、JSON對象全等判斷:當(dāng)強迫癥遇到數(shù)據(jù)結(jié)構(gòu)
1.1 精確匹配(鍵順序敏感)
-- 案例:查找配置完全相同的設(shè)備(鍵順序必須一致) SELECT * FROM device_configs WHERE config_json = '{"resolution": "1080p", "brightness": 80}'; -- 陷阱警告:以下兩個JSON會被認(rèn)為不同(鍵順序不同) '{"a":1, "b":2}' vs '{"b":2, "a":1}'
1.2 松散全等判斷(鍵順序無關(guān))
-- 方法:使用JSON_CONTAINS雙向包含 + 長度相同 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; -- 確保沒有多余字段
二、數(shù)組的“靈魂拷問”式查詢
2.1 數(shù)組完全相等(順序敏感)
-- 查找tags數(shù)組嚴(yán)格等于["VIP","北京"]的用戶(順序、數(shù)量、元素完全一致) SELECT * FROM users WHERE tags_json = CAST('["VIP","北京"]' AS JSON);
2.2 數(shù)組包含所有元素(順序無關(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 多層級路徑查詢
-- 查找住在"北京朝陽區(qū)"的用戶(嵌套對象查詢) SELECT * FROM users WHERE address_json->>'$.city' = '北京' AND address_json->>'$.district' = '朝陽區(qū)';
3.2 通配符搜索所有層級
-- 查找任意層級包含"error_code":500的日志(遞歸搜索) SELECT * FROM service_logs WHERE JSON_SEARCH(log_json, 'all', '500', NULL, '$**.error_code') IS NOT NULL;
3.3 深度過濾數(shù)組對象
-- 查找訂單中有商品ID=100且數(shù)量>2的訂單(數(shù)組對象過濾) SELECT * FROM orders WHERE JSON_EXISTS( items_json, '$[*]?(@.product_id == 100 && @.quantity > 2)' );
四、混合條件綜合查詢
4.1 JSON字段 + 關(guān)系字段聯(lián)合查詢
-- 查找2023年后注冊,且擴(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)查詢
-- 查找購物車總價>1000且包含"急件"標(biāo)簽的訂單 SELECT * FROM orders WHERE CAST(cart_info->>'$.total_price' AS DECIMAL) > 1000 AND JSON_CONTAINS(tags_json, '"急件"');
4.3 動態(tài)條件生成查詢
-- 根據(jù)前端傳入的JSON過濾條件動態(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)化后(提取時間到獨立字段 + 索引) 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)換陷阱
-- 錯誤:字符串與數(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)難
-- 錯誤:左模糊查詢?nèi)頀呙? SELECT * FROM articles WHERE content_json->>'$.text' LIKE '%重要通知%'; -- 正確:使用全文索引或?qū)S盟阉饕妫ㄈ鏓lasticsearch)
6.3 大JSON修改雪崩
-- 錯誤:頻繁更新大JSON字段導(dǎo)致IO飆升 UPDATE user_activities SET log_json = JSON_ARRAY_APPEND(log_json, '$', '新事件') WHERE user_id = 1001; -- 正確:拆分成關(guān)系表或分片存儲
七、超硬核面試題
題目:如何高效實現(xiàn)JSON數(shù)組的交集查詢?
示例:查找tags數(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)計(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql啟動提示:錯誤2系統(tǒng)找不到指定文件的解決方案
這篇文章主要給大家介紹了mysql啟動提示:錯誤2系統(tǒng)找不到指定文件的解決方案,文中通過圖文結(jié)合的方式給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案
在MySQL中用很多類型的自增ID,每個自增ID都設(shè)置了初始值,一般情況下初始值都是從0開始,然后按照一定的步長增加(一般是自增 1),下面這篇文章主要給大家介紹了關(guān)于mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案,需要的朋友可以參考下2023-04-04mysql使用自定義序列實現(xiàn)row_number功能(步驟詳解)
這篇文章主要介紹了mysql使用自定義序列實現(xiàn)row_number功能,本文分步驟通過實例代碼給大家介紹的非常詳細(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)定版的各個亮點,感興趣的小伙伴們可以學(xué)習(xí)參考一下2019-10-10