当前位置: 首页 > article >正文

深入理解 MySQL 中 FIND_IN_SET 函数在查询中的应用

在 MySQL 数据库操作中,FIND_IN_SET函数是一个非常实用的工具,特别是在处理一些非规范化数据存储结构时,它能发挥出独特的作用。本文将结合一个具体的菜单表结构案例,深入探讨FIND_IN_SET函数的用法。

1. 表结构介绍

我们有一个名为test_menu的表,用于存储菜单信息。其表结构如下:

CREATE TABLE `test_menu` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `parent_id` int DEFAULT NULL,
  `path` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
  • id:菜单的唯一标识,自增长。
  • name:菜单的名称。
  • parent_id:父菜单的 ID,用于表示菜单的层级关系。
  • path:存储该菜单到根菜单的路径,以某种方式编码,这里可能是包含各级菜单id的字符串,以逗号分隔。

2. FIND_IN_SET 函数的基本原理

FIND_IN_SET函数的语法为FIND_IN_SET(str,strlist),它用于在以逗号分隔的字符串列表strlist中查找指定的字符串str。如果找到,返回该字符串在列表中的位置(从 1 开始);如果未找到,则返回 0。

3. 具体查询案例分析

我们来看下面的查询语句:

SELECT
    parent.* 
FROM
    test_menu m
    LEFT JOIN test_menu parent ON FIND_IN_SET( parent.id, m.path ) 
WHERE
    m.NAME = '二级 - 1';
  1. 整体逻辑:这个查询的目的是,先从test_menu表中找到名称为二级 - 1的菜单记录(用别名m表示),然后通过LEFT JOIN操作,将这些记录与test_menu表自身(用别名parent表示)进行连接。连接条件是parent表中的id存在于m表的path字段所包含的逗号分隔的字符串列表中。最终返回满足条件的parent表中的记录。

  2. 分步解析

    • 第一步:筛选出符合名称条件的记录WHERE m.NAME = '二级 - 1'这部分条件,会从test_menu表中筛选出名称为二级 - 1的所有记录。这些记录构成了后续连接操作的左表。
    • 第二步:连接操作LEFT JOIN test_menu parent ON FIND_IN_SET( parent.id, m.path ),这里使用FIND_IN_SET函数作为连接条件。对于左表(即名称为二级 - 1的记录)中的每一条记录,FIND_IN_SET( parent.id, m.path )会在其path字段中查找parent表中每一条记录的id。如果找到,就将对应的parent表记录与左表记录进行连接。因为是LEFT JOIN,所以即使在path字段中找不到匹配的id,左表的记录也会出现在结果集中,只是对应的parent表字段值为NULL

4. 示例数据及结果展示

假设我们在test_menu表中有如下数据:

idnameparent_idpath
1一级 - 1NULL1
2二级 - 111,2
3二级 - 211,3
4三级 - 121,2,4
5三级 - 221,2,5
6三级 - 331,3,6

当执行上述查询语句时,因为m.NAME = '二级 - 1',所以首先筛选出id为 2 的记录。其path字段值为1,2
LEFT JOIN过程中,parent表中id为 1 和 2 的记录满足FIND_IN_SET( parent.id, m.path )条件(即12都存在于1,2这个字符串列表中)。所以最终的查询结果会包含parent表中id为 1 和 2 的记录,即:

idnameparent_idpath
1一级 - 1NULL1
2二级 - 111,2

5. 注意事项

虽然FIND_IN_SET函数在这种场景下很方便,但需要注意以下几点:

  1. 性能问题:在大数据量的情况下,使用FIND_IN_SET函数可能会导致性能下降。因为这种查询方式无法利用索引进行高效查找,数据库需要对每一条记录进行字符串匹配操作。
  2. 数据规范化:从数据库设计的角度来看,使用path字段存储以逗号分隔的路径信息并非最优方案。规范化的设计应该通过外键关联来明确菜单的层级关系,这样在查询和维护数据时会更加高效和可靠。

综上所述,FIND_IN_SET函数在处理特定场景下的非规范化数据时有其独特的优势,但在实际应用中,需要根据具体情况权衡其利弊,确保数据库的性能和数据的一致性。

希望通过本文的介绍,能让你对FIND_IN_SET函数在 MySQL 中的应用有更深入的理解。在实际开发中,合理运用该函数可以解决一些看似棘手的数据查询问题。


http://www.kler.cn/a/505718.html

相关文章:

  • Android 高德地图API(新版)
  • 算法竞赛(蓝桥杯)贪心算法1——数塔问题
  • vim使用指南
  • 计算机的错误计算(二百一十二)
  • 4种革新性AI Agent工作流设计模式全解析
  • vue 文件下载实现
  • 美化IDE之修改IDEA启动界面logo图片
  • laravel中请求失败重试的扩展--Guzzle
  • 【Hive】海量数据存储利器之Hive库原理初探
  • mysql,PostgreSQL,Oracle数据库sql的细微差异(2) [whith as; group by; 日期引用]
  • 24-25-1-单片机开卷部分习题和评分标准
  • SpringBoot工程快速启动
  • Chatper 4: Implementing a GPT model from Scratch To Generate Text
  • 为独特工作流设计 K8s 健康检查(Design k8s Health Check for Unique Workflow)
  • citrix netscaler13.1 重写负载均衡响应头(基础版)
  • 如何利用.NET版PDF处理控件Aspose.PDF,使用 C# 从 PDF 中删除水印
  • SpringCloud-Alibaba搭建
  • 用 Python 从零开始创建神经网络(二十二):预测(Prediction)/推理(Inference)(完结)
  • 1.5 安装Kuboard在页面上熟悉k8s集群
  • 使用verilog设计推箱子游戏
  • C#,任意阶幻方(Magic Square)的算法与源代码
  • 【GRACE学习-1】JPL数据下载
  • BI 是如何数据分析的?
  • 汉图科技XP356DNL高速激光打印一体机综合性能测评
  • 高斯数据库 Shell 脚本:批量执行多个 SQL 文件
  • 【线性代数】行列式的性质