首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL FIND_IN_SET 用法詳解:逗號分隔字串查詢與效能權衡

     編輯:MySQL 資料庫相關知識

函數定義

FIND_IN_SET(str, strlist)
-- 回傳 str 在 strlist 中的位置 (1-based),找不到回傳 0
-- strlist 格式:'a,b,c,d' (逗號分隔,無空格)

典型應用:權限位元組存儲

-- user 表
id | username | purview (VARCHAR)
1  | alice    | '1,3,5'
2  | bob      | '2,4'

-- 查擁有權限 1 的用戶
SELECT * FROM user WHERE FIND_IN_SET('1', purview) > 0;

優缺點分析

效能實測 (參考)

  • 10 萬筆資料,`FIND_IN_SET` 全表掃描 ~200ms
  • 同資料正規化 `user_permission` 表 + 索引,JOIN 查詢 ~2ms
  • **差距 100 倍**

最佳實務建議

  1. **新系統嚴禁**此設計,採用**多對多關聯表** (`user_id`, `perm_id`)
  2. **舊系統若必須維持**:
    • 資料量 < 1 萬可接受
    • 加 `CHECK (purview REGEXP '^[0-9]+(,[0-9]+)*$')` 限制格式
    • 唯讀查詢可建立**物化視圖** 或 **觸發器同步正規化表**
  3. 查詢時 `FIND_IN_SET('1', purview)` **優於** `purview LIKE '%,1,%' OR purview LIKE '1,%' OR purview = '1'` (邏輯完整、可讀性高)

結語

`FIND_IN_SET` 是**歷史包袱**的權宜之計。**新專案請正規化設計**,舊專案評估遷移成本,若無法遷移請控制資料量並輔以同步索引表。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
優點缺點
單欄位存多值,減少關聯表**違反第一正規化 (1NF)**,原子性破壞
查詢語法簡潔**無法使用索引** (全表掃描),大量資料極慢
避免 JOIN 開銷更新複雜 (需字串拼接/替換),易產生臭蟲
適用靜態、小量、唯讀場景聚合統計 (如統計每個權限人數) 需掃全表