mysql - 如何在 MySQL 中检查 BIT 数据类型?
问题描述
我在users
表中有一个名为permissions
. 像这样:
// users
+---------+-----------------+-------------+
| id | permissions | name |
+---------+-----------------+-------------+
| int(11) | bit(15) | varchar(20) |
+---------+-----------------+-------------+
| 1 | 001100001111101 | Jack |
| 2 | 111111111111111 | Peter |
| 3 | 110000000111011 | Martin |
+---------+-----------------+-------------+
如您所见,permissions
列具有bit(15)
数据类型。该值的每一位都决定了一个用户能力。例如,第一位指的是voting
-ability,第二位指的是commenting
-ability ant等...
我也有一个触发器BEFORE UPDATE
,可以像这样调查该权限:
SELECT permissions INTO @deleting_permission FROM users WHERE id = new.deleter_id;
IF old.deleted <> new.deleted THEN
IF (IFNULL((@deleting_permission & b'10000000000' > 0), 0) < 1) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You cannot delete post";
END IF;
END IF;
它总是抛出:
你不能删除帖子
即使对于具有权限值的#2 用户也是如此。111111111111111
那么有什么问题呢?
注意到我permissions
像这样更新列:
-- To give some specific accesses (permissions) to the user
UPDATE users SET permissions = b'111111000101011' WHERE id = ?
-- To give full access (permissions) to the user
UPDATE users SET permissions = -1 WHERE id = ?
解决方案
如果要使用该BIT
类型,则需要使用按位运算符,而不是常规运算符。例如,如果您想检查用户是否将最左边的位设置为权限,您可以执行以下&
操作:
SELECT permissions INTO @p FROM users WHERE id = new.deleter_id;
IF old.deleted <> new.deleted THEN
IF (b'100000000000000' & @p = 0)
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You cannot delete post";
END IF;
END IF;
上面的基本思想是,文字b'100000000000000'
用作掩码,可用于检测最左边的位(并且只有该位)是否设置为 1。如果设置为 1,则&
操作不会返回 0。
具有权限的用户111111111111111
拥有所有权限的原因是任何掩码检查位都会返回 true。
推荐阅读
- java - 我不明白如何移动树的一部分
- node.js - Objection.js/Knex.js 查询错误(错误:带有时区的时间戳类型的输入语法无效:“null”)
- mongodb - Docker中的SpringBoot未连接到服务器上的Mongo(非Dockerized)
- redirect - 如何创建将 Google Home 重定向到广播电台的 Google Action Intent?
- python - Python Pillow 和 Tkinter 通过调整窗口大小来调整图像大小
- cloud - 多次记录光子云上open unity 可执行文件的性能测试
- php - mysql优化一个类别的广告数量
- python - 如何通过匹配其他列中的值来填充列子集中的缺失值?
- database - Future Builder中来自snapshot.data的Flutter Floor数据库?
- r - 多元线性回归的循环