語法
& :
按位與,二進(jìn)制位同時都為1的位設(shè)為1潮孽。
| :
按位或,二進(jìn)制位有一個位為1就為1.
^ :
按位異或筷黔,對應(yīng)位的二進(jìn)制數(shù)不同時往史,對應(yīng)位的結(jié)果才為1;如果兩個對應(yīng)位數(shù)都為0或者都為1佛舱,則對應(yīng)位的結(jié)果為0椎例。
原理
$a = 6 轉(zhuǎn)化為2進(jìn)制為 110
$b = 3 轉(zhuǎn)化為2進(jìn)制為 11
$a & $b即是 110 與 11
將$a和$b中都為1的位設(shè)為1,位數(shù)不夠的補(bǔ)0.即110 與 011
運(yùn)算結(jié)果010,轉(zhuǎn)化為十進(jìn)制結(jié)果為2
應(yīng)用場景
每個景點(diǎn)包含很多屬性挨决,例如適合旅游的月份,我們一般的做法可能有兩種:
- 是增加一個
varchar
字段订歪,每個月份之間用一個特殊符號分隔保存脖祈,例如:"1,2,22,65,7"
- 建立一個關(guān)系表,在這里不能使用1-12的數(shù)字來表示月份,而是使用
1刷晋,2盖高,4,8眼虱,16喻奥,32,64捏悬,128撞蚕,512,1024过牙,2048甥厦,4096
來表示,如果是多個月份寇钉,可以相互組合相加刀疙,之后存儲為一個值。
比如 1,10,12月份扫倡,就可以存儲1+512+4096=4609
,4096 這個值庙洼。
這個技巧適用于屬性較少的一對多的場景,可以存儲1個或者多個镊辕,太多的話還是推薦試用關(guān)系表油够。常用的屬性有:月份,消息提醒類型征懈,各種有限的類型組合等等石咬。
使用技巧:
-- 添加一個分類 用 “|”
SELECT (4|2|1); --- = 7
-- 去掉一個分類,用“^”
SELECT 7 ^ 1;
-- 當(dāng)我們需要查詢某個月份的景點(diǎn)時卖哎,例如查詢3月份的景點(diǎn)鬼悠,可使用以下語句:
SELECT * FROM `spots` WHERE `month` & 4 = 4;
-- 當(dāng)設(shè)置某個景點(diǎn)適合某個月份時,例如設(shè)置4325的景點(diǎn)適合2月份亏娜,可使用下面的語句:
UPDATE `spots` SET `month` = `month` | 2 WHERE `id` = 4325
-- 當(dāng)取消設(shè)置某個景點(diǎn)的月份時焕窝,可使用下面的語句:
UPDATE `spots` SET` month` = `month` ^ 2 WHERE`id`= 4325
-- 查詢同時適合多個月份的數(shù)據(jù),例如需要查詢設(shè)置了11维贺,12它掂,1月份的景點(diǎn),將其三個月份對應(yīng)的數(shù)值加起來,結(jié)果為6145虐秋,然后使用這個數(shù)值進(jìn)行查詢:
SELECT * FROM `spots` WHERE `month` & 6145 = 6145
-- 查詢只要適合榕茧,1,11,12月份其中一個月份的景點(diǎn)就行
SELECT * FROM `spots` WHERE (`month` & 4096 = 4096) or (`month` & 2048 = 2048) or (`month` & 1 = 1)