位運算是將給定的操作數轉化為二進制后,對各個操作數每一位都進行指定的邏輯運算,得到的二進制結果轉換為十進制數后就是位運算的結果。MySQL 5.0 支持6 種位運算符,如表4-4 所示。
可以發現,位運算符中的位與“&”和位或“|”和前面介紹的邏輯與和邏輯或非常類似。其他操作符和邏輯操作有所不同,下面將分別舉例介紹。
“位與”對多個操作數的二進制位作邏輯與操作,例如2&3,因為2 的二進制數是10,3 是11,所有10&11 的結果是10,十進制數字還是2,來看實際結果:
mysql> select 2&3; +-----+ | 2&3 | +-----+ | 2 | +-----+ 1 row in set (0.00 sec)
可以對2 個以上操作數做或操作,測試一下2&3&4,因為4 的二進制是100,和上面的10做與操作100&010 后,結果應該是000,可以看實際結果為:
mysql> select 2&3&4; +-------+ | 2&3&4 | +-------+ | 0 | +-------+ 1 row in set (0.00 sec)
“位或”對多個操作數的二進制位作邏輯或操作,還是上面的例子,2|3 的結果應該是10|11,結果還是11,應該是3,實際結果如下:
mysql> select 2|3; +-----+ | 2|3 | +-----+ | 3 | +-----+ 1 row in set (0.00 sec)
“位異或”對操作數的二進制位做異或操作,10^11 的結果是01,結果應該是1,可以看實際結果為:
mysql> select 2^3; +-----+ | 2^3 | +-----+ | 1 | +-----+ 1 row in set (0.00 sec)
“位取反”對操作數的二進制位作NOT 操作,這里的操作數只能是一位,下面看一個經典的取反例子:對1 做位取反,具體如下所示:
mysql> select ~1 ,~ 18446744073709551614; +----------------------+------------------------+ | ~1 | ~ 18446744073709551614 | +----------------------+------------------------+ | 18446744073709551614 | 1 | +----------------------+------------------------+ 1 row in set (0.00 sec)
結果讓大家可能有些疑惑,1 的位取反怎么會是這么大的數字?來研究一下,在MySQL 中,常量數字默認會以8 個字節來表示,8 個字節就是64 位,常量1 的二進制表示為63 個“0”加1 個“1”,位取反后就是63 個“1”加一個“0”,轉換為二進制后就是18446744073709551614,實際結果如下:
mysql> select bin(18446744073709551614); +------------------------------------------------------------------+ | bin(18446744073709551614) | +------------------------------------------------------------------+ | 1111111111111111111111111111111111111111111111111111111111111110 | +------------------------------------------------------------------+ 1 row in set (0.00 sec)
“位右移”對左操作數向右移動右操作數指定的位數。例如100>>3,就是對100 的二進制數0001100100 右移3 位,左邊補0,結果是0000001100,轉換為二進制數是12,實際結果如下:
mysql> select 100>>3; +--------+ | 100>>3 | +--------+ | 12 | +--------+ 1 row in set (0.00 sec)
“位左移”對左操作數向左移動右操作數指定的位數。例如100<<3,就是對100 的二進制數0001100100 左移3 位,右邊補0,結果是1100100000,轉換為二進制數是800,實際結果如下:
mysql> select 100<<3; +--------+ | 100<<3 | +--------+ | 800 | +--------+ 1 row in set (0.00 sec)
2.mysql 的優先級
前面介紹了MySQL 支持的各種運算符的使用方法。在實際應用中,很可能將這些運算符進行混合運算,那么應該先進行哪些運算符的操作呢?表4-5 中列出了所有的運算符,優先級由低到高排列,同一行中的運算符具有相同的優先級。
在實際運行的時候,可以參考表4-5 中的優先級。實際上,很少有人能將這些優先級熟練記憶,很多情況下我們都是用“()”來將需要優先的操作括起來,這樣既起到了優先的作用,又使得其他用戶看起來更加易於理解。