数据库单字段存储多个标签(位移操作)

24 篇文章 0 订阅
17 篇文章 0 订阅

在上周的开发中看到了这样的一个问题 一个员工有多个资质
如: 资质 1=监理,2=安全员,4=项目经理,8=技术员,16=特种作业人员,32=劳务人员 (是2的倍数 就是二进制的10进制的展示 )
李白 1=监理 4=项目经理
一般我们的解决方式有以下两种

  1. 在员工表这里扩展字段
  2. 配置资质表 和 一个关系表 然后链表查询

方案1 没有使用的原因 是因为这个资质可能会频繁的增加 修改 就要频繁的改表结构了 数据量一大 改表结构就不是一个好的操作
方法2 这里没有使用的原因 就是这个用工查询本身就关联表过多了 要不就要2次请求数据库

演示

这里写了一个Demo 提供一下思路
首先准备一个员工表

CREATE TABLE `emp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `deptid` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `empno` int(11) DEFAULT NULL,
  `del_flag` int(11) DEFAULT '0',
  `record_version` int(255) DEFAULT '1',
  `qualification` int(11) NOT NULL COMMENT '1=监理2=安全员4=项目经理8=技术员16=特种作业人员32=劳务人员',
  PRIMARY KEY (`id`),
  KEY `i` (`age`,`deptid`,`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4;

使用这个qualification 字段来表示 这个员工的资质

插入

比如 上述例子 李白 拥有 1=监理 4=项目经理 这两个资质 插入sql 如下:

-- 在Java 中资质可以是多个 使用 mybatis的 foreach
insert into emp (name,qualification) values ('李白',  1<<0  | 1<<4) 

在这里插入图片描述

查询

数据:
在这里插入图片描述

-- 1=监理,2=安全员,4=项目经理,8=技术员,16=特种作业人员
-- 在Java 中资质可以是多个 使用 mybatis的 foreach
select name,
(attrbute & (1<<0) !=0) as 监理,
(attrbute & (1<<1) !=0) as 安全员,
(attrbute & (1<<2) !=0) as 项目经理,
(attrbute & (1<<3) !=0) as 技术员,
(attrbute & (1<<4) !=0) as 特种作业人员,
(attrbute & (1<<5) !=0) as 劳务人员
from emp
where
attrbute != 0

结果
在这里插入图片描述

统计

select 
sum((qualification & (1<<0) !=0)) as 监理,
sum((qualification & (1<<1) !=0)) as 安全员,
sum((qualification & (1<<2) !=0)) as 项目经理,
sum((qualification & (1<<3) !=0)) as 技术员,
sum((qualification & (1<<4) !=0)) as 特种作业人员,
sum((qualification & (1<<5) !=0)) as 劳务人员
from emp
where
qualification != 0

条件查询

select *
from emp
where
qualification != 0
# 仅查询监理 
and  qualification & 1 !=0
--------------------------------------------
select *
from emp
where
qualification != 0
# 仅查询监理 并且是 项目经理  
and qualification & ( 1<<0  | 1<<4) = (1<<0  | 1<<4)
---------------------------------------
select *
from emp
where
qualification != 0
# 仅查询监理 或 项目经理  
and qualification & ( 1<<0  | 1<<4) != 0

修改 减少标签

--Java 中资质可以是多个 使用 mybatis的 foreach
update emp set  qualification = qualification ^ (1<<4) where  id  = 19 

查看结果

select id , name,(qualification & (1<<0) !=0) as 监理,
(qualification & (1<<1) !=0) as 安全员,
(qualification & (1<<2) !=0) as 项目经理,
(qualification & (1<<3) !=0) as 技术员,
(qualification & (1<<4) !=0) as 特种作业人员,
(qualification & (1<<5) !=0) as 劳务人员 from emp where  id  = 19 

在这里插入图片描述

修改 增加标签

--Java 中资质可以是多个 使用 mybatis的 foreach
update emp set  qualification = qualification | (1<<4) where  id  = 19 

查看结果

select id , name,(qualification & (1<<0) !=0) as 监理,
(qualification & (1<<1) !=0) as 安全员,
(qualification & (1<<2) !=0) as 项目经理,
(qualification & (1<<3) !=0) as 技术员,
(qualification & (1<<4) !=0) as 特种作业人员,
(qualification & (1<<5) !=0) as 劳务人员 from emp where  id  = 19 

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值