如果一个MySQL字段包含多个ID,应该如何解决呢?下面就为您介绍一个处理单个MySQL字段包含多个ID的处理方法,希望对您能有所启迪。

多端合一响应式网站:PC+平板+手机,同一后台修改数据多端同步更新提交您的需求,获取网站建设与营销策划方案报价,我们会在1小时内与您联系!
以下是一个MySQL字段包含多个ID的解决办法完整的例子。
1、新建表
- create table Category
 - (
 - cateId int(5) not null AUTO_INCREMENT,
 - chiName varchar(80),
 - primary key (cateId)
 - );
 - drop table if exists OpenRecord;
 - create table OpenRecord
 - (
 - opreId int(5) not null AUTO_INCREMENT,
 - cateIds varchar(80),
 - primary key (opreId)
 - );
 
2、初始化数据
- insert Category(chiName) values ('fish'),('shrimp'),('crab'),('tiger');
 - insert OpenRecord(cateIds) values('1,2');
 - insert OpenRecord(cateIds) values('2,3');
 
3、查询OpenRecord中Id为1包括的Category。
#错误的方法
- select *
 - from Category
 - where (select INSTR(cateIds,cateId) from OpenRecord where opreId=1)
 
#正确的方法
- select *
 - from Category
 - where (select FIND_IN_SET(cateId,cateIds) from OpenRecord where opreId=1)
 
用INSTR会出现当ID大于10的时候,查ID为1的数据,会把1,10,11,12......的都拿出来。
4、扩展会出现的问题。
 用FIND_IN_SET可以解决ID是用","号隔开的问题。然而会有另外的两种情况。
A、当ID不包含",",但是用别的符号分开时,如用"|"。我们有如下的解决办法
- select *
 - from Category
 - where (select FIND_IN_SET(cateId,REPLACE(cateIds,'|',',')) from OpenRecord where opreId=1)
 
如果你的这种情况的表很多。我们也可以把它写成函数。(MYSQL 5 下通过)
- DELIMITER $$
 - DROP FUNCTION IF EXISTS fun_instr$$
 - CREATE FUNCTION fun_instr(ns VARCHAR(100),s TEXT,isplit CHAR(1))
 - RETURNS INT(8)
 - BEGIN
 - DECLARE strPosition INT(8);
 - SET strPosition = FIND_IN_SET(ins,REPLACE(s,split,','));
 - RETURN strPosition;
 - END$$
 - DELIMITER ;
 
#使用方法
- select *
 - from Category
 - where (select fun_instr(cateId,cateIds,',') from OpenRecord where opreId=1)
 
B、当ID包含",",但是用别的符号分开时,如用"|"。用上面的方法是行不通的。我们有如下的解决办法
- DELIMITER $$
 - DROP FUNCTION IF EXISTS fun_custom_instr$$
 - CREATE FUNCTION fun_custom_instr(ins VARCHAR(255),s TEXT,split VARCHAR(10))
 - RETURNS INT(8)
 - BEGIN
 - DECLARE splitlen INT(2);
 - DECLARE strPosition INT(8);
 - SET splitLen = LENGTH(split);
 - SET strPosition = 0;
 - #第一段的字符相等
 - IF s=ins THEN
 - RETURN 1;
 - END IF;
 - #中间段的字符相等
 - WHILE INSTR(s,split)>0 DO
 - SET strPositionstrPosition = strPosition + 1;
 - IF LEFT(s,INSTR(s,split)-1)=ins THEN
 - RETURN strPosition;
 - END IF;
 - SET s = SUBSTRING(s,INSTR(s,split) + splitLen);
 - END WHILE;
 - #最一段的字符相等
 - IF s=ins THEN
 - RETURN strPosition+1;
 - END IF;
 - RETURN 0;
 - END$$
 - DELIMITER ;
 
#使用方法
- select *
 - from Category
 - where (select fun_custom_instr(cateId,cateIds,',') from OpenRecord where opreId=1)
 
5、总结
 以上方法虽然能解决我们的问题,但数据量大的时候速度较慢。彻底的解决办法是设计数据库的时候按照数据库的范式来做。
 现在的空间基本已经不是问题,硬件已经很便宜了。