mysql中查詢json類型字段的關鍵在于掌握json函數和優化技巧。1. json字段以二進制格式存儲,插入時使用json字符串;2. 使用json_extract()提取鍵值,路徑表達式如’$.age’,結合->和->>操作符簡化寫法;3. 在where條件中查詢json字段時性能較低,建議通過生成列配合索引優化查詢效率;4. 查詢包含數組的json字段可用json_contains()函數判斷是否存在指定值,注意參數需為帶引號的字符串。合理運用這些方法可實現高效查詢。
在mysql中,JSON類型字段的引入讓結構化數據和非結構化數據可以在同一個表里共存。尤其在處理一些配置項、擴展信息或動態數據時,JSON字段非常實用。但很多人用的時候會卡在“怎么查”這個問題上,其實只要掌握幾個關鍵函數和使用技巧,就能輕松應對大部分查詢場景。
1. JSON字段的基本結構與存儲方式
MySQL中的JSON類型字段并不是簡單的字符串,它內部是經過解析的二進制格式,這意味著你在插入或更新時寫的是文本形式的JSON字符串,但數據庫內部會自動轉換成可高效訪問的結構。
舉個例子:
CREATE TABLE users ( id INT PRIMARY KEY, info JSON );
插入一條記錄:
INSERT INTO users (id, info) VALUES (1, '{"name": "Tom", "age": 25, "hobbies": ["reading", "gaming"]}');
這時候info字段就保存了一個完整的JSON對象,你可以通過內置函數來提取其中的內容。
2. 提取JSON字段中的值:常用函數介紹
要在查詢中使用JSON字段里的內容,最常用的函數是 JSON_EXTRACT(),它的作用是從JSON對象中提取某個鍵的值。
比如想查出所有年齡大于20歲的用戶:
SELECT * FROM users WHERE JSON_EXTRACT(info, '$.age') > 20;
還可以結合別名使用:
SELECT id, JSON_EXTRACT(info, '$.name') AS name FROM users;
注意:$.age 是JSON路徑表達式,表示根層級下的age字段。如果是嵌套結構,比如”address”:{“city”:”Beijing”},路徑就是’$.address.city’。
除了提取,還有一些輔助函數也很有用:
- JSON_UNQUOTE():去掉引號,讓結果更干凈
- -> 操作符(等價于 JSON_EXTRACT)
- ->> 操作符(等價于 JSON_UNQUOTE(JSON_EXTRACT()))
比如:
SELECT id, info->'$.name' AS name, info->>'$.name' AS clean_name FROM users;
3. 在WHERE條件中使用JSON字段的注意事項
雖然可以用JSON字段做查詢,但在性能上有一些限制。因為JSON字段本身不是索引友好的,直接對它進行查詢可能效率不高。
如果你經常需要根據某個JSON字段的值做篩選,建議你配合生成列(Generated column) 和 索引 來優化。
比如你想根據用戶的name頻繁查詢:
ALTER TABLE users ADD COLUMN name VARCHAR(100) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(info, '$.name'))) STOred; CREATE INDEX idx_name ON users(name);
這樣之后就可以像普通字段一樣查詢了:
SELECT * FROM users WHERE name = 'Tom';
這種方式在大數據量下性能提升非常明顯。
4. 查詢包含數組類型的JSON字段
有時候JSON字段中會包含數組,比如前面例子中的hobbies字段是一個字符串數組。
如果你想查找“愛好里有gaming”的用戶,可以這樣做:
SELECT * FROM users WHERE JSON_CONTaiNS(info->'$.hobbies', '"gaming"');
注意幾點:
- JSON_CONTAINS 的第二個參數要寫成帶引號的字符串(即'”gaming”‘),否則會匹配失敗。
- 如果是數字,也是一樣,例如'”25″‘。
如果你要判斷是否包含多個值中的任意一個,可以配合子查詢或者IN語句使用。
基本上就這些。JSON字段在MySQL中使用起來靈活方便,但也容易因為不了解其特性而寫出低效的查詢。掌握幾個核心函數、理解路徑語法,并合理利用生成列和索引,就能讓它既好用又高效。