mysql作为常用的关系型数据库,提供了丰富的位运算符来支持二进制数据的处理,这些运算符可以直接对整数类型的二进制位进行操作,在数据状态标记、权限控制、特征存储等场景中应用十分广泛。
mysql支持的位运算符类型
mysql内置了多种位运算符,不同运算符对应不同的二进制位操作逻辑,常用的位运算符如下表所示:
| 运算符 | 名称 | 作用说明 |
|---|---|---|
| & | 按位与 | 两个操作数的对应二进制位都为1时,结果位为1,否则为0 |
| | | 按位或 | 两个操作数的对应二进制位有一个为1时,结果位为1,否则为0 |
| ^ | 按位异或 | 两个操作数的对应二进制位不同时,结果位为1,否则为0 |
| ~ | 按位取反 | 对操作数的每个二进制位取反,1变0,0变1 |
| << | 左移 | 将操作数的二进制位向左移动指定位数,右侧补0 |
| >> | 右移 | 将操作数的二进制位向右移动指定位数,左侧补0 |
位运算符的基础使用示例
我们可以通过简单的查询语句来观察不同位运算符的执行结果,以下示例基于mysql的整数类型数据展开:
-- 按位与运算,5的二进制是101,3的二进制是011,按位与结果为001即1 SELECT 5 & 3 AS and_result; -- 按位或运算,5|3的二进制结果为111即7 SELECT 5 | 3 AS or_result; -- 按位异或运算,5^3的二进制结果为110即6 SELECT 5 ^ 3 AS xor_result; -- 按位取反运算,对5取反,结果和mysql的整数位数有关,这里以64位为例结果是-6 SELECT ~5 AS not_result; -- 左移运算,5的二进制101左移1位变成1010即10 SELECT 5 << 1 AS left_shift_result; -- 右移运算,5的二进制101右移1位变成10即2 SELECT 5 >> 1 AS right_shift_result;
位运算符处理二进制数据的常见场景
多状态标记存储
当需要存储一个实体的多个布尔类型状态时,不需要为每个状态单独创建字段,可以用一个整数类型的字段,每个二进制位对应一个状态,通过位运算符来设置和读取状态。
比如我们有一个用户表,需要存储用户是否具有发帖、评论、上传附件三个权限,我们可以用字段user_permission来存储,第0位代表发帖权限,第1位代表评论权限,第2位代表上传附件权限。
-- 创建用户表,permission字段用INT类型存储权限状态
CREATE TABLE user_info (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
user_permission INT DEFAULT 0
);
-- 插入一个用户,默认没有任何权限,user_permission为0
INSERT INTO user_info (username) VALUES ('test_user');
-- 给用户添加发帖权限,发帖权限对应第0位,1左移0位是1,用按位或运算设置
UPDATE user_info SET user_permission = user_permission | (1 << 0) WHERE id = 1;
-- 给用户添加评论权限,评论权限对应第1位,1左移1位是2
UPDATE user_info SET user_permission = user_permission | (1 << 1) WHERE id = 1;
-- 查询用户是否有发帖权限,用按位与运算,结果大于0表示有权限
SELECT id, username,
CASE WHEN (user_permission & (1 << 0)) > 0 THEN '有发帖权限' ELSE '无发帖权限' END AS post_permission,
CASE WHEN (user_permission & (1 << 1)) > 0 THEN '有评论权限' ELSE '无评论权限' END AS comment_permission
FROM user_info WHERE id = 1;
-- 移除用户的评论权限,用按位异或或者按位与加取反的组合,这里用按位与加取反
UPDATE user_info SET user_permission = user_permission & ~(1 << 1) WHERE id = 1;
二进制数据特征匹配
如果表中存储了二进制类型的特征数据,我们也可以通过位运算符来匹配符合特征要求的记录。
比如我们有一个商品表,用feature字段存储商品的特性,第0位代表是否支持包邮,第1位代表是否支持7天无理由退货,第2位代表是否支持货到付款。
-- 创建商品表
CREATE TABLE product_info (
id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(100) NOT NULL,
feature INT DEFAULT 0
);
-- 插入测试数据,第一个商品支持包邮和7天无理由,第二个商品支持包邮和货到付款
INSERT INTO product_info (product_name, feature) VALUES
('商品A', (1 << 0) | (1 << 1)),
('商品B', (1 << 0) | (1 << 2));
-- 查询所有支持包邮的商品
SELECT * FROM product_info WHERE (feature & (1 << 0)) > 0;
-- 查询同时支持包邮和货到付款的商品
SELECT * FROM product_info WHERE (feature & ((1 << 0) | (1 << 2))) = ((1 << 0) | (1 << 2));
使用位运算符的注意事项
- 位运算符的操作数一般是整数类型,如果是其他类型,mysql会自动转换为整数后再进行运算,可能会出现结果不符合预期的情况。
- 按位取反运算符
~的结果和mysql的整数位数有关,比如32位和64位环境下的结果会不同,使用时需要注意环境差异。 - 左移和右移运算时,移动的位数不能超过操作数类型的位数范围,否则结果可能出现异常。
- 如果存储的状态超过64个,INT类型(64位)无法满足需求,可以考虑使用BIT类型或者拆分多个字段存储。
位运算符处理二进制数据的效率远高于用多个字段存储状态后逐个判断的方式,在状态数量较多的场景下,合理使用位运算符可以大幅减少字段数量,提升查询和更新的效率。
mysql位运算符二进制数据bitwise_operator修改时间:2026-06-28 14:15:43