mysql 条件位运算实现多值存储

mysql 条件位运算实现多值存储

MySQL 处理

mysql 条件位运算位运算实现多值存储,方法适合数据范围有限,且不会变更

在业务上往往会出现多选的情况,例:选择 周一 至 周日 随意组合;

数据在设计时就会如何去储存

一种是一般是在储存是以某种方式隔开,例如:1,2,3代表选择了 周一、 周二、周三

另一种就是使用,mysql的位运算;字段类型为 int(3)

七个二进制分别代表 周一 至 周日 0未选 1选中,例: 选择了周日、周一、 周二

周六 周五 周四 周三 周二 周一 周日
0 0 0 0 1 1 1

对应 二进制位:0000111,数据库储存十进制:7

二进制 十进制
周日 0000001 1
周一 0000010 2
周二 0000100 4
周三 0001000 8
周四 0010000 16
周五 0100000 32
周六 1000000 64

数据库存的数据

id weeks
1 1
2 2
3 4
4 8
5 5
6 127
7 126
8 7
-- 查询包含周三的
SELECT * FROM test_weeks WHERE weeks & 8;
-- SELECT * FROM test_weeks WHERE weeks & POWER(2,3);
-- orical语法
-- SELECT * FROM test_weeks WHERE bitand(weeks, power(2, 3)) != 0;
-- SELECT * FROM test_weeks WHERE bitand(weeks, 8) != 0;
-- 查询不包含周三的
SELECT * FROM test_weeks WHERE !(weeks & 8);
-- 查询包含周日or周三的
SELECT * FROM test_weeks WHERE weeks & (1+8);
SELECT * FROM test_weeks WHERE weeks & 1 or weeks & 8;
-- 查询包含周日and周三的
SELECT * FROM test_weeks WHERE weeks & 1 and weeks & 8;

 
-- 新增周三周四
UPDATE test_weeks set weeks = weeks + 8 + 16 WHERE id = 3
-- 减少周三周四
UPDATE test_weeks set weeks = weeks - 8 - 16 WHERE id = 3

释:

-- 查询包含周三的
SELECT * FROM test_weeks WHERE weeks & 8;

-- 查询结果
-- id  weeks
-- 4   8
-- 6   127
-- 7   126

查到127是因为:

127     =    1111111
8       =    0001000
&
---->   =    0001000  = 8
结果不是0,即满足条件为 true,所以能查出来
&(与)运算即:两位同时为“1”,结果才为“1”,否则为0

Java工具类

枚举:周日:0,周一:1,周二:2,周三:3,周四:4,周五:5,周六:6

public class MathUtils {
    private final static char[] DIGITS = {'0', '1'};

    public static int quadraticSum(int... nums) {
        // return Arrays.stream(nums).map(i -> (int) Math.pow(2, i)).sum();
        return Arrays.stream(nums).map(i -> i == 0 ? 1 : 2 << (i - 1)).sum();
    }

    public static Integer quadraticSum(List<Integer> nums) {
        if (Objects.isNull(nums) || nums.isEmpty()) {
            return null;
        }
        return nums.stream().mapToInt(i -> i).map(i -> i == 0 ? 1 : 2 << (i - 1)).sum();
    }
    
    public static List<Integer> quadraticSolution(int num) {
        List<Integer> solutionList = new ArrayList<>();
        // Integer.toBinaryString() 源码
        int rCharPos = 0;
        do {
            int index = num & 1;
            if (index == 1) {
                solutionList.add(rCharPos);
            }
            ++rCharPos;
            num >>>= 1;
        } while (num != 0);
        return solutionList;
    }

    public static void main(String[] args) {
        System.out.println(quadraticSum(1, 2));
        System.out.println(quadraticSolution(6));
        System.out.println(quadraticSum(0, 4));
        System.out.println(quadraticSolution(17));
        System.out.println(quadraticSum(1, 2, 3));
        System.out.println(quadraticSolution(14));
        System.out.println(quadraticSum(2, 4));
        System.out.println(quadraticSolution(20));
        System.out.println(quadraticSum(0));
        System.out.println(quadraticSolution(1));
    }
}
posted @ 2022-11-25 15:21  Zzzy君不见  阅读(326)  评论(0)    收藏  举报