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));
}
}