go 使用二进制位记录数据状态值

go 使用二进制位记录数据状态值

在日常开发中,我们经常会遇到一条数据,同时会有多个状态或者多种类型值时.
例如: 一个老师的职位,可能是班主任,同时也是语文老师,也可能是学校主任.
职位对应编号
1-班主任; 2-语文老师;3-学校主任

传统方式:
id姓名职位
1张三1,2,3

传统方式在进行班主任进行检索时, contrains('1')的方式进行检索, 会将职位为10,11等的信息查找出来. 不符合我们的检索结果

建立关系表方式:
id姓名
1张三
用户id职位id
11
12
13

使用链表查询的方式,可以检索到数据.
优点: 数据集清晰
缺点: 需要链表查询, 如果用户信息还有其他表,这个时候需要多个表进行链表,效率低

使用二进制位的方式
id姓名职位
1张三7

职位使用二进制位进行存储,SELECT * FROM 用户名 WHERE 职位字段名 & 1
优点: 少建一张表, 减少一次链表查询
缺点:
1.可读性差,职位存储值不能直观读取
2.如果使用sql进行与查询,不能走索引; 如果要走索引,使用in方法,in的值换算方法https://blog.csdn.net/qq_35392791/article/details/123842022
使用建议:
1.类型变化较少的字段,如少量的职位、状态等
2.值类型应从1,2,3,4,5连续设置, 尽量让每个二进制位都为1

代码
将二进制位转换为十进制数
// 入参: 切片(二进制对应位)  
// 1,2,3,4 对应的二进制 00001111// 结果: 7  
func SliceToOb(d []int) int {  
res := 0  
for _,v := range d {  
res |= 1 << (v-1)  
} return res  
}

将十进制数转换为对应二进制位置数据

// 入参: 十进制数  
// 将十进制数转换为二进制1对应位  
// 运算过程:  
// 12&1                (12 >> 1) 即为 6&1      (6 >> 1) 3&1     (3>>1) 1&1    (1>>1) 0// 00001100             00000110            00000011      00000001  
// &   0001             &  0001            &  0001      &  0001  
// ---------         ----------           --------      --------  
// 00000000             00000000            00000001      00000001  
// 为0不记录位置信息      为0不记录位置信息        为1记录位置信息   为1记录位置信息   为0则遍历位置结束  
// 开始下一位二级制计算  
  
// 结果: [1,3]  
func ObToSlice(d int) []int {  
 res := make([]int, 0)  
 i := 1  
 flag := true  
 for flag {  
 if d == 0 {  
 flag = false  
 break  
 }  
 if d & 1 != 0 {  
 res = append(res, i)  
 } i++  
 d = d >> 1  
 }  
 return res  
}
调用演示
func main()  {  
 res := SliceToOb([]int{1,2,3})  
 fmt.Printf("%d,%08b\n",res,res)  
 res2 := ObToSlice(res)  
 fmt.Printf("%+v\n",res2)  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值