在 MySQL 开发中,字段查询几乎每天都会遇到。
尤其是在:
- Laravel 项目开发
- 电商系统
- 权限管理
- 标签系统
- 商品分类
- 多选字段存储
这些业务场景里,经常会看到一种数据:
1,2,3,5,8
例如:
用户角色
商品标签
支持站点
分类 ID
权限列表
很多老项目都会直接把多个值:
用逗号存进一个字段
于是:
FIND_IN_SET()
这个 MySQL 函数就出现了。
很多开发者知道它。
但真正了解它:
- 返回值
- 使用场景
- 性能问题
- 隐藏坑点
的人其实并不多。
今天就结合实际开发场景,详细聊聊:
- FIND_IN_SET() 是什么
- 它到底返回什么
- 为什么很多老项目喜欢用
- 为什么它其实有性能风险
- Laravel 中的实际场景
- 什么情况下不推荐使用
一、FIND_IN_SET() 是什么
基本语法
FIND_IN_SET(查找值, 字段)
作用:
在逗号分隔字符串中查找某个值
二、最基础用法
例如:
SELECT FIND_IN_SET('php', 'java,php,mysql');
结果:
2
因为:
php 在第 2 个位置
三、没找到会返回什么?
例如:
SELECT FIND_IN_SET('python', 'java,php,mysql');
结果:
0
注意:
不是 false
而是:
0
四、实际开发中的高频场景
1、多角色字段
例如:
roles = '1,2,3'
查询包含管理员角色:
SELECT *
FROM users
WHERE FIND_IN_SET(1, roles);
2、商品支持站点
例如:
upload_site = 'us,uk,ca'
查询支持美国站:
WHERE FIND_IN_SET('us', upload_site)
五、Laravel 中的常见写法
例如:
DB::table('product')
->whereRaw("FIND_IN_SET(?, upload_site)", ['us'])
->get();
很多 ERP 系统里都能看到这种写法。
六、为什么很多人喜欢用?
因为:
开发方便
例如:
原本需要:
中间表
很多人直接:
逗号拼接
就解决了。
尤其是:
- 老系统
- 快速开发项目
- 小型后台
非常常见。
七、但它其实有很大性能问题
这是很多人不知道的地方。
八、FIND_IN_SET() 基本无法走索引
例如:
WHERE FIND_IN_SET('us', upload_site)
MySQL 通常需要:
全表扫描
原因:
字段内容不是标准结构化数据
而是:
字符串解析
九、数据量小时感觉不到
很多开发者测试时:
几千条数据
感觉:
很快
但当:
几十万
几百万
数据量出现后。
性能会明显下降。
十、为什么它不适合大型系统?
因为:
关系型数据库本质上不适合存 CSV 字符串
例如:
1,2,3,4
这种结构:
- 无法高效索引
- 不利于统计
- 不利于 JOIN
- 不利于优化
十一、正确设计其实应该用中间表
例如:
用户角色关系:
user_role
表:
| user_id | role_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
查询时:
JOIN
效率会高很多。
十二、为什么老项目还是很多?
因为:
开发成本低
很多时候:
业务先跑起来
后面再优化。
所以:
FIND_IN_SET()
在:
- WordPress 插件
- ERP 系统
- CMS 系统
- 老 Laravel 项目
中依然非常常见。
十三、开发中的常见坑
1、空字符串问题
例如:
FIND_IN_SET('us', '')
结果:
0
2、NULL 问题
例如:
FIND_IN_SET('us', NULL)
结果:
NULL
不是:
0
很多人容易忽略。
十四、实际开发建议
小数据量项目
可以使用:
FIND_IN_SET()
开发会比较快。
大数据量项目
建议:
中间表
不要:
逗号存字段
否则:
- SQL 很难优化
- 索引失效
- 查询越来越慢
十五、总结
FIND_IN_SET() 是 MySQL 中一个:
看起来方便
但隐藏问题很多
的函数。
它特别适合:
- 小型项目
- 老系统
- 快速开发
但:
并不适合大型高并发系统
很多开发者前期觉得:
真方便
但项目数据量上来后。
往往都会开始后悔:
为什么当初不用中间表
这也是很多 MySQL 老项目里的经典历史遗留问题。
温馨提示:
本文最后更新于
2026-05-17 22:09:27,若文章内容或图片失效,请留言或联系站长反馈!
© 版权声明
本文发表于「海知新」,转载请注明出处。本站内容仅用于学习、记录与技术交流,部分资源来源于互联网,如有侵权请联系删除。
THE END














暂无评论内容