资讯专栏INFORMATION COLUMN

MySQL主表存储以逗号分隔id时的增删改查操作

MadPecker / 520人阅读

摘要:案例查询系统用户关联的产品关联的应用难点表通过一个字段维护所有关联的产品的集合。

案例1:查询系统用户(993318396439445506)关联的产品关联的应用
 [sys_user]      [sys_user_prod]     [product]   [app]
 
  uid-------------user_id         /---id----------products
                                 /
                  prod_id-------/

难点: app表通过一个字段products维护所有关联的产品id的集合。如:2 或 4,11,12

实现:

SELECT `id`,`uuid`,`name`,`token`,`time`,`products` FROM app
where CONCAT(",",products,",") REGEXP
(
  SELECT CONCAT(
      ",{1}(",
      GROUP_CONCAT(prod_id SEPARATOR "|") ,
      "),{1}"
  )
  FROM sys_user_prod WHERE user_id = "993318396439445506"
)
order by id;

片段理解1:
假设products=1,17 --> CONCAT(",",products,",") --> ,1,17,

片段理解2:

 SELECT CONCAT(
     ",{1}(",
     GROUP_CONCAT(prod_id SEPARATOR "|") ,
     "),{1}"
 )
 FROM sys_user_prod WHERE user_id = "993318396439445506"

拆分来理解:

SELECT prod_id FROM sys_user_prod WHERE user_id = "993318396439445506";

以上sql会产生多行,所以使用group_concat函数将多上拼接起来:1|17|19

SELECT group_concat(prod_id SEPARATOR "|") FROM sys_user_prod WHERE user_id = "993318396439445506";

最后使用concat拼接处正则表达式:,{1}(1|17|19),{1}

SELECT concat(",{1}(",   group_concat(prod_id SEPARATOR "|")    ,"),{1}") FROM sys_user_prod WHERE user_id = "993318396439445506";

所以,where子句后面的,实际内容是这样的:

SELECT `id`,`uuid`,`name`,`token`,`time`,`products` FROM app
where CONCAT(",",products,",") REGEXP ",{1}(1|17|19),{1}" order by id;
案例2:查询终端用户(36)关联的设备

场景:“点击某个终端用户,显示该用户所有设备

 [user]             [device]

 id--------- /-----id
             x
 devices----/ -----users

难点:多对多

实现1(不推荐):

SELECT * FROM device WHERE concat(",",id,",") REGEXP
(SELECT CONCAT(",{1}(", REPLACE(devices,",","|"), "),{1}") FROM `user` WHERE id = 36);

首先看看用户表的devices, result --> 3,6

select * from user where id = 36;

逐步拼接正则匹配条件, result --> 3|6

SELECT REPLACE(devices,",","|") FROM `user` WHERE id = 38;

逐步拼接正则匹配条件, result --> ,{1}(3|6),{1}

SELECT CONCAT(",{1}(", REPLACE(devices,",","|"), "),{1}") FROM `user` WHERE id = 36;

所以,where子句后面的,实际内容是这样的:

SELECT * FROM device WHERE concat(",",id,",") REGEXP ",{1}(3|6),{1}";

实现2(推荐):

SELECT * FROM device WHERE id REGEXP
(SELECT CONCAT("^(", REPLACE(devices,",","|"), ")$") FROM `user` WHERE id = 36);

实际内容是这样的:

SELECT * FROM device WHERE id REGEXP "^(3|6)$";

实现3(强烈推荐):

SELECT * FROM device WHERE FIND_IN_SET(id, (SELECT devices FROM `user` WHERE id = 36) );
案例3:查询设备(3)下面所有终端用户

场景:显示某个设备下关联的所有终端用户的信息

 [user]             [device]

 id--------- /-----id
             x
 devices----/ -----users

实现1(不推荐):

SELECT
  d.id as device_id,
  d.name as device_name,
  d.users as device_users,
  u.`id` AS user_id,
  u.`name` AS user_name,
  u.`phone` AS user_phone,
  u.`wechat` AS user_wechat,
  u.`devices` AS user_devices
FROM device d, `user` u
WHERE d.`id` = 3
AND u.`id` REGEXP CONCAT("^(",REPLACE(d.`users`, ",", "|"),")$");

实现2(推荐):

SELECT
  d.id as device_id,
  d.name as device_name,
  d.users as device_users,
  u.`id` AS user_id,
  u.`name` AS user_name,
  u.`phone` AS user_phone,
  u.`wechat` AS user_wechat,
  u.`devices` AS user_devices
FROM device d, `user` u
WHERE d.`id` = 3 AND FIND_IN_SET(u.`id`,d.`users`);
案例4:删除产品(7)下面关联的服务(25)

场景:删除产品下面某个服务,需要在产品表中删除对应的服务id

 [product]       [service]           [service_property]

 id           /--id              /----id
             /                  /
 services---/    properties----/

实现:

UPDATE product SET services =
SUBSTR(
    REPLACE(
        CONCAT(",",services), CONCAT(",",25), ""
        ), 2
    )
    WHERE id = 7;

理解,从查询开始理解,避免删除错了:

select id,name,services from product where id = 7;

现在知道services的值是24,25,26,27

思路是先用concat将 "24,25,26,27" 变成 ",24,25,26,27"

再用replace将 ",24,25,26,27" 中的 ",25" 替换成空字符串 "",处理后字符串变成",24,26,27"

由于最前面多了一个逗号,所以最后用substr来去掉那个多余的逗号

select substr(
    replace(
        concat(",",services),concat(",",25),""
    ),2
) from product where id = 7;
案例5:产品(7)下面添加关联的服务(33)

场景:添加产品下面某个服务,需要在产品表中添加对应的服务id

 [product]       [service]           [service_property]

 id           /--id              /----id
             /                  /
 services---/    properties----/

实现:

UPDATE product SET services = CONCAT(services,",",33) WHERE id = 7;

理解,从查询开始理解,避免添加错了:

select CONCAT(services,",",33) from product WHERE id = 7;
案例6:删除服务(5)下面所有关联的属性

场景:删除产品下面某个服务,需要先删除服务下面关联的属性

 [product]       [service]           [service_property]

 id           /--id              /----id
             /                  /
 services---/    properties----/

实现1(不推荐):

DELETE FROM service_property WHERE id
REGEXP CONCAT( "^(", REPLACE( (SELECT properties FROM service WHERE id = 5),  ",",  "|" ), ")$");

理解:从查询开始理解,避免删除错了:

result --> 13,14,15

select properties from service where id = 5;

替换 result --> 13|14|15

select REPLACE( (SELECT properties FROM service WHERE id = 5),  ",",  "|" );

拼接成正则 result --> ^(13|14|15)$

select CONCAT( "^(", REPLACE( (SELECT properties FROM service WHERE id = 5),  ",",  "|" ), ")$");

最后就可以用来匹配属性id:

select id,name from service_property where id
REGEXP CONCAT( "^(",
                REPLACE( (SELECT properties FROM service WHERE id = 2),  ",",  "|" ),
               ")$");

实现2(强烈推荐):

select id,name from service_property where
FIND_IN_SET(id,(SELECT properties FROM service WHERE id = 6));

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/47744.html

相关文章

  • 迈出全栈第一步,vue+node+mysql独立完成前后端分离的增删改流程

    摘要:本使用创建本地服务器,在就能完成全部流程,并不需要线上服务器。路径要与后端接口一致。后端返回成功后,前端数据中对应的元素也要删掉,更新视图。控制器里拿一个方法出来说一下吧,完整的代码都在。读取操作完成后调用释放连接。 写在前面 本文只是本人学习过程的一个记录,并不是什么非常严谨的教程,希望和大家一起共同进步。也希望大家能指出我的问题。适合有一定基础,志在全栈的前端初学者学习,从点击按钮...

    pakolagij 评论0 收藏0
  • 迈出全栈第一步,vue+node+mysql独立完成前后端分离的增删改流程

    摘要:本使用创建本地服务器,在就能完成全部流程,并不需要线上服务器。路径要与后端接口一致。后端返回成功后,前端数据中对应的元素也要删掉,更新视图。控制器里拿一个方法出来说一下吧,完整的代码都在。读取操作完成后调用释放连接。 写在前面 本文只是本人学习过程的一个记录,并不是什么非常严谨的教程,希望和大家一起共同进步。也希望大家能指出我的问题。适合有一定基础,志在全栈的前端初学者学习,从点击按钮...

    fsmStudy 评论0 收藏0
  • MySQL的基本使用——简单的增删改

    摘要:是现在使用最多的关系型数据库,我们下面来学习一下如何用语句进行基本的创建数据库创建表向表中插入数据从表中删除数据更新表等操作。对表进行删除操作女执行结果如下图,可以看到,性别为女的数据已经被删除了。以上就是数据库的一些简单操作。 MySQL是现在使用最多的关系型数据库,我们下面来学习一下如何用sql语句进行基本的创建数据库、创建表、向表中插入数据、从表中删除数据、更新表等操作。1.创建...

    mylxsw 评论0 收藏0
  • MySQL: 表的增删改(基础)

    摘要:注释在中可以使用空格描述来表示注释说明即增加查询更新删除四个单词的首字母缩写。 1.CRUD 注释:在SQL中可以使用–空格+描述来表示注释说明CRUD 即增加...

    RobinTang 评论0 收藏0
  • SQL语法 MySQL数据库

    摘要:数据库管理系统的全称是,简称。命令的语法表名数据库约束约束是表上强制执行的数据校验规则,约束主要用于保证数据库里数据的完整性。 SQL语句是对所有关系数据库都通用的命令语法,而JDBC API只是执行SQL语句的工具,JDBC允许对不同的平台、不同的数据库采用相同的编程接口来执行SQL语句 关系数据库基本概念和MySQL基本命令 数据库仅仅是存放用户数据的地方。当用户访问、操作数据库中...

    xeblog 评论0 收藏0

发表评论

0条评论

MadPecker

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<