项目二进制标位实战应用
本文最后更新于:2021年6月15日 晚上
四月已过大半,紧急补上一篇博客,本文将讲解二进制状态位在项目中的实战应用,技术原理很简单,就是利用二级制与位运算实现。这种方式的应用场景还是比较广泛,希望对你有用~
本文首发于个人博客:http://nullpointer.pw/binary-tag.html
更新日志:
2020-11-22 11:00:43: 增加数据库查询过滤示例
前言
举个栗子,需要保存这些状态你会怎么设计表呢?
你可能会想,这很简单啊,针对一个开关加一个状态字段嘛~
呵呵真是太年轻,这样开发上线后,产品又要增加新的提醒方式,如图
难不成,再加状态字段?
可以发现,以上这种做法,在需求改动时就会很蛋疼,而且这只是提醒的开关设置,若有其他类型的开关设置就更加麻烦。
所以这里引入今天的主题,二进制状态位。
二进制与位运算
这样数据库只需要添加一个整数字段保存即可。使用2的次幂值代表一种状态,比如使用 1
(2º) 代表开启站内提醒,2
(2¹) 代表 开启邮件提醒,4
(2²) 代表开启短信提醒等等,这样这个状态位字段只需要存储 7
即可表示已开启这几项提醒。因为 7 与这几个状态值进行与运算时都等于状态值本身,如果不等于则为开启。
首先回顾一下二进制与位运算的基础知识
十进制 | 二进制 |
---|---|
0 | 0000 0000 |
1 | 0000 0001 |
2 | 0000 0010 |
3 | 0000 0011 |
4 | 0000 0100 |
5 | 0000 0101 |
6 | 0000 0110 |
7 | 0000 0111 |
或运算:bit位上有1为1。例如:2 | 1 == 0000 0010 | 0000 0001 == 3
与运算:bit位都为1才为1。 例如 5 & 2 == 0000 0101 & 0000 0010 == 0
实际应用
以上文提醒开关为例:
现在打开 站内提醒,不打开邮件提醒,打开短信提醒,最终的值的计算方法为:1 | 4 = 5
1 |
|
现在判断是否打开了站内提醒
5 & 1 == 0000 0101 & 0000 0001 == 1
1 |
|
现在要关闭站内提醒
5 ^ 1 == 0000 0101 ^ 0000 0001 == 4
1 |
|
测试:
1 |
|
使用优化
在日常开发中,这些状态可以通过枚举值进行封装起来,方便使用。
1 |
|
数据库状态筛选
评论中有同学提到
如果现在有需求 需要过滤其中一个状态值 怎么操作
对于这个问题其实也是可以实现的,因为 SQL 也是支持位运算的。比如有个表字段名称为 notice_flags,现在要筛选所有开启了 EMAIL
提醒方式的所有记录,SQL 中可以这么写(#{flag} 为 EMAIL 的 flag 值)
1 |
|
这条 SQL 会进行与运算,查询出所有符合条件的记录。
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!