多个开关标志位存储的设计思路

前端时间配合前端需求的时候出现一个场景,需要存储大量的state状态,例如是否开启推送、短信、夜间模式等状态。如果使用单表多字段去存这些信息就显得得不偿失。考虑到开关只有开关状态的情况下,使用01二进制的方式来存可能非常不错。

mysql数据库中:INT类型(0,4 294 967 295)可存储10位数字,也就是可以表示10个标志位开关。一般是够用的,如果不够那么可以考虑BIGINT(0,18 446 744 073 709 551 615)扩展到20位,比如:010101010101001010100......。

如果说20位还是不满足我们业务需求,那么其实存储的时候进行2进制转10进制,10位的1111111111转换成10进制只有1023一个SMALLINT类型即可存储。最大优化了mysql的存储内容,那么为什么我们要考虑直接用二进制的方式存呢,其实就是为了方便易读,如果是个标志位情况那么11110,最低位表示推送开关,那么只要我们字段注释写的ok,代表的含义基本上是非常清楚的,推送处于关闭状态。

数据库存储解决了,那么在程序里面应该如何更方便的存储呢?刚开始考虑到考虑到可以用二进制运算来方便运算。

如果当前场景有三个标志位,‘101’来表示 ‘open close open’ 三个开关。

场景1:我想知道某个开关是否开启

  private static boolean getBit(int num, int i)
   {
      //true 表示第i位为1,否则为0
      return ((num & (1 << i)) != 0);
   }
复制代码

场景2:开启功能

    //将 整数 num 的第 i 位的值 置为 1
    private static int getBit(int num, int i)
    {
        return (num | (1 << i));
    }
复制代码

场景3:关闭功能

    //将 整数 num 的第 i 位的值 置为 1
    private static int getBit(int num, int i)
    {
       int mask = ~(1 << i);
       return (num & (mask));
    }复制代码

实际应用配合缓存,这样操作的效率感觉还是可以的。

如有不妥之处,请指明谢谢。


转载于:https://juejin.im/post/5a7feeff5188257a7c6c4be9

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值