mysql中查詢json類型字段的關(guān)鍵在于掌握json函數(shù)和優(yōu)化技巧。1. json字段以二進(jìn)制格式存儲,插入時使用json字符串;2. 使用json_extract()提取鍵值,路徑表達(dá)式如’$.age’,結(jié)合->和->>操作符簡化寫法;3. 在where條件中查詢json字段時性能較低,建議通過生成列配合索引優(yōu)化查詢效率;4. 查詢包含數(shù)組的json字段可用json_contains()函數(shù)判斷是否存在指定值,注意參數(shù)需為帶引號的字符串。合理運(yùn)用這些方法可實(shí)現(xiàn)高效查詢。
在mysql中,JSON類型字段的引入讓結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)可以在同一個表里共存。尤其在處理一些配置項(xiàng)、擴(kuò)展信息或動態(tài)數(shù)據(jù)時,JSON字段非常實(shí)用。但很多人用的時候會卡在“怎么查”這個問題上,其實(shí)只要掌握幾個關(guān)鍵函數(shù)和使用技巧,就能輕松應(yīng)對大部分查詢場景。
1. JSON字段的基本結(jié)構(gòu)與存儲方式
MySQL中的JSON類型字段并不是簡單的字符串,它內(nèi)部是經(jīng)過解析的二進(jìn)制格式,這意味著你在插入或更新時寫的是文本形式的JSON字符串,但數(shù)據(jù)庫內(nèi)部會自動轉(zhuǎn)換成可高效訪問的結(jié)構(gòu)。
舉個例子:
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對象,你可以通過內(nèi)置函數(shù)來提取其中的內(nèi)容。
2. 提取JSON字段中的值:常用函數(shù)介紹
要在查詢中使用JSON字段里的內(nèi)容,最常用的函數(shù)是 JSON_EXTRACT(),它的作用是從JSON對象中提取某個鍵的值。
比如想查出所有年齡大于20歲的用戶:
SELECT * FROM users WHERE JSON_EXTRACT(info, '$.age') > 20;
還可以結(jié)合別名使用:
SELECT id, JSON_EXTRACT(info, '$.name') AS name FROM users;
注意:$.age 是JSON路徑表達(dá)式,表示根層級下的age字段。如果是嵌套結(jié)構(gòu),比如”address”:{“city”:”Beijing”},路徑就是’$.address.city’。
除了提取,還有一些輔助函數(shù)也很有用:
- JSON_UNQUOTE():去掉引號,讓結(jié)果更干凈
- -> 操作符(等價于 JSON_EXTRACT)
- ->> 操作符(等價于 JSON_UNQUOTE(JSON_EXTRACT()))
比如:
SELECT id, info->'$.name' AS name, info->>'$.name' AS clean_name FROM users;
3. 在WHERE條件中使用JSON字段的注意事項(xiàng)
雖然可以用JSON字段做查詢,但在性能上有一些限制。因?yàn)镴SON字段本身不是索引友好的,直接對它進(jìn)行查詢可能效率不高。
如果你經(jīng)常需要根據(jù)某個JSON字段的值做篩選,建議你配合生成列(Generated column) 和 索引 來優(yōu)化。
比如你想根據(jù)用戶的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';
這種方式在大數(shù)據(jù)量下性能提升非常明顯。
4. 查詢包含數(shù)組類型的JSON字段
有時候JSON字段中會包含數(shù)組,比如前面例子中的hobbies字段是一個字符串?dāng)?shù)組。
如果你想查找“愛好里有g(shù)aming”的用戶,可以這樣做:
SELECT * FROM users WHERE JSON_CONTaiNS(info->'$.hobbies', '"gaming"');
注意幾點(diǎn):
- JSON_CONTAINS 的第二個參數(shù)要寫成帶引號的字符串(即'”gaming”‘),否則會匹配失敗。
- 如果是數(shù)字,也是一樣,例如'”25″‘。
如果你要判斷是否包含多個值中的任意一個,可以配合子查詢或者IN語句使用。
基本上就這些。JSON字段在MySQL中使用起來靈活方便,但也容易因?yàn)椴涣私馄涮匦远鴮懗龅托У牟樵儭U莆諑讉€核心函數(shù)、理解路徑語法,并合理利用生成列和索引,就能讓它既好用又高效。