需求举例:
某动物园对动物的投喂有如下规定:
苹果能够去投喂鹿、猴子、熊猫
竹子能够去投喂熊猫、竹鼠
树叶能够去投喂兔子、鹿
如今饲养员携带苹果、树叶,他能够投喂哪些动物?mysql
分析
上述情景中,饲养员、动物针对投放的食物在多种条件下匹配且最少有一项符合条件就确认投喂sql
位运算 &
简单回顾 & 的用法
按位“与”操做符,<font color = red>若是两个数的二进制,相同位数都是1,则改位结果为1,不然是0</font>。如下举例:数据库
int a = 5; int b = 4; 5的二进制:0000 0000 0000 0101 4的二进制:0000 0000 0000 0100 a & b = 0000 0000 0000 0100 0000 0000 0000 0100 ==> 4 //转为十进制是4
借助 &
- mysql支持位运算的操做逻辑,如
SELECT * FROM table WHERE a & 5 <> ?;
- 回到上面的需求,假设咱们使用位运算,可让苹果表明个位、竹子表明十位、树叶就表明百位(二进制下),因为二进制下每一位只有0和1的值,那么能够规定该动物容许投喂这种食物赋值1,不容许投喂就赋值0。以鹿为例:吃苹果、不吃竹子、吃树叶,则用二进制表示为101:
1 0 1 吃树叶 不吃竹子 吃苹果
- 保存数据库时,101就是鹿的喂食数据,将二进制转为十进制101 —> 5,即保存鹿信息时,有一个食物的字段的数据为5
- 上面的需求,要去查询容许投喂苹果、树叶的动物,作条件筛选时请求会携带着要查询食物参数,那么该请求参数先进行处理为101(同上面的方式)-> 5,那么咱们能够把 {food:5} 放入请求中,后台接收处理
- 如今咱们一个个比较下各动物的投食数据:
鹿的食物信息为 101 -> 5
猴子的食物信息 100 -> 4
熊猫的食物信息 110 -> 6
竹鼠的食物信息 010 -> 2
兔子的食物信息 001 -> 1code
菜单 | 鹿 | 猴子 | 熊猫 | 竹鼠 | 兔子 |
---|---|---|---|---|---|
数据运算 | 5 & 5 | 4 & 5 | 6 & 5 | 2 & 5 | 1 & 5 |
转为二进制 | 101 & 101 | 100 & 101 | 110 & 101 | 010 & 101 | 001 & 101 |
结果 | 101 -> 5 | 100 -> 4 | 100 -> 4 | 000 -> 0 | 001 -> 1 |
从上面的结果能够得出,惟一不符合条件的动物为竹鼠,其通过位运算后的值是0,其余只要存在符合项就要大于0。SQL应为:table
SELECT name FROM zoo_animal WHERE food & 5 > 0;
便可查寻出全部的符合条件的动物class
变动
所有符合
假如如今需求更改,必须是肯定这个动物既吃苹果又吃树叶才容许投递(必须条件一致,很少很多),那么改成:后台
SELECT name FROM zoo_animal WHERE (food & 5) = 5;
条件规则
新增: 如今又多了一种食物,好比香蕉,如今动物信息表中全部的数据都是基于苹果、竹子、树叶所整合出来的,如何作到最小的变更,咱们可让每一次新增的食物的位放到最前面,如今就是千位上表明香蕉,由于新添加的食物不会出如今本来的动物身上,因此本来的动物就变成了:二进制
鹿: 0101 -> 5 猴子: 0100 -> 4 熊猫的食物信息: 0110 -> 6 竹鼠的食物信息: 0010 -> 2 兔子的食物信息: 0001 -> 1
咱们知道在位数前面加0,是不会更改数值的,若是运行本来动物吃香蕉,只需走从新维护动物信息的请求便可请求
删除: 删除不一样于添加,删除的数据没有肯定性,假如咱们如今删除了竹子的信息,那么全部的食物信息都会出现差错,因此咱们须要作一个规则的重建,即删除掉某一个信息时,应该从新把动物的食物信息从新按规则构建:im
鹿: 11 -> 3 猴子: 10 -> 2 熊猫的食物信息: 10 -> 2 竹鼠的食物信息: 00 -> 0 兔子的食物信息: 01 -> 1
修改:修改同删除,但实际场景出现的可能性较少(自我感受,应该没人会去调整食物的排列顺序)