資料庫設計時,常將多值屬性以逗號分隔儲存於單一欄位(如文章類型:1,3,4 代表「頭條、熱點、圖文」)。傳統 LIKE '%4%' 易誤判(如匹配到 14、40),且無法使用索引。FIND_IN_SET 專為此場景設計。
FIND_IN_SET(str, strlist)
str:要搜尋的字串(如 '4')。strlist:逗號分隔的字串列表(如欄位 type 值 '1,3,4')。strlist 為空回傳 0,任一參數為 NULL 回傳 NULL。str 包含逗號,函式將無法正常運作。-- 建立測試資料
CREATE TABLE `article` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(100),
`type` VARCHAR(50) -- 儲存 '1,3,4' 等逗號分隔值
);
INSERT INTO `article` (`title`, `type`) VALUES
('文章A', '1,3,4'),
('文章B', '2,4'),
('文章C', '1,2');
-- 查詢所有包含類型 4(圖文)的文章
SELECT * FROM `article` WHERE FIND_IN_SET('4', `type`);
-- 等同於
SELECT * FROM `article` WHERE `type` REGEXP '[[:<:]]4[[:>:]]'; -- 但 FIND_IN_SET 效能更好且語意清晰
SET 型別欄位,MySQL 會優化為位元運算,速度極快。VARCHAR 儲存的逗號列表,無法直接使用索引。若查詢頻繁且資料量大,建議正規化設計:建立關聯表 article_type (article_id, type_id)。FIND_IN_SET 參數中使用函式或運算,否則無法利用優化。LIKE:WHERE type LIKE '%4%' 會匹配到 14, 40, 41 等非預期值。'1, 3, 4'(逗號後有空格),搜尋 '3' 會失敗。存入前應 REPLACE(type, ' ', '') 或應用層保證無空格。適用版本:MySQL 5.0+。MariaDB 同樣支援。