需求舉例:
某動物園對動物的投喂有如下規定:
蘋果能夠去投喂鹿、猴子、熊貓
竹子能夠去投喂熊貓、竹鼠
樹葉能夠去投喂兔子、鹿
如今飼養員攜帶蘋果、樹葉,他能夠投喂哪些動物?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
修改:修改同刪除,但實際場景出現的可能性較少(自我感受,應該沒人會去調整食物的排列順序)