使用 MySQL 这么多年,这几天是我第一次知道 MySQL 竟然存在 BIT
这种数据类型。位模式的操作,最大名鼎鼎的应该是 「 布隆过滤器 ( Bloom Filter ) 」。
MySQL 中的位模式字面量一般使用 b'val'
或 0bval
语法,val
是只包含 0
和 1
的二进制值,字符 b
之前有无 0
都无关紧要,但要注意的是 0b
是区分大小写的,0b
不能写为 0B
,但 b
由不限大小写。b001
和 B001
是一个意思。这也是匪夷所思了。
以下这些是合法的位类型字面量
b'01'
B'01'
0b01
而下面这些,则是非法的位类型字面量
b'2' (2 不是合法的二进制数字 )
0B01 (0B 必须是 0b)
默认情况下,位类型的字面量是一个二进制字符串
mysql> SELECT b'1000001', CHARSET(b'1000001');
+------------+---------------------+
| b'1000001' | CHARSET(b'1000001') |
+------------+---------------------+
| A | binary |
+------------+---------------------+
mysql> SELECT 0b1100001, CHARSET(0b1100001);
+-----------+--------------------+
| 0b1100001 | CHARSET(0b1100001) |
+-----------+--------------------+
| a | binary |
+-----------+--------------------+
位类型字面量可以有一个可选的字符集介绍器和 COLLATE
子句,用于指定为使用特定字符集和排序规则的字符串
[_charset_name] b'val' [COLLATE collation_name]
例如
mysql> SELECT _latin1 b'1000001';
+--------------------+
| _latin1 b'1000001' |
+--------------------+
| A |
+--------------------+
1 row in set (0.01 sec)
mysql> SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;
+----------------------------------------+
| _utf8 0b1000001 COLLATE utf8_danish_ci |
+----------------------------------------+
| A |
+----------------------------------------+
1 row in set (0.02 sec)
注意: 示例使用
b'val'
表示法,但0bval
表示法也是可以的
在数值上下文中,MySQL 会把位类型的数据转换为相应的整型。所以,如果要确保对位类型字面值进行数字处理,请在数字上下文中使用它。
至于如何做到这一点,可以在把这个位类型数据进行 + 0
操作或者使用 CAST (... AS UNSIGNED)
转换器。
例如,默认情况下,分配给用户定义变量的位字面量是二进制字符串。如果要将值指定为数字,请在数字上下文中使用它:
mysql> SET @v1 = b'1100001';
mysql> SET @v2 = b'1100001'+0;
mysql> SET @v3 = CAST(b'1100001' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+------+------+------+
| @v1 | @v2 | @v3 |
+------+------+------+
| a | 97 | 97 |
+------+------+------+
空位值 b''
将被计算为零长度二进制字符串。转换为数字则位 0
:
mysql> SELECT CHARSET(b''), LENGTH(b'');
+--------------+-------------+
| CHARSET(b'') | LENGTH(b'') |
+--------------+-------------+
| binary | 0 |
+--------------+-------------+
mysql> SELECT b''+0;
+-------+
| b''+0 |
+-------+
| 0 |
+-------+
位类型的 0b
或 b
语法可以方便的指定要分配给 BIT
列的值
mysql> CREATE TABLE t (b BIT(8));
mysql> INSERT INTO t SET b = b'11111111';
mysql> INSERT INTO t SET b = b'1010';
mysql> INSERT INTO t SET b = b'0101';
在查询时,结果集中的位值将作为二进制值返回,可读性就会差很多,这时候我们可以将它们转换为十进制或者十六进制,我们可以使用转换函数 bin()
或 hex()
两个函数来完成这种转换。转换的时候会忽略高位中的 0
mysql> SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
+------+----------+--------+--------+
| b+0 | BIN(b) | OCT(b) | HEX(b) |
+------+----------+--------+--------+
| 255 | 11111111 | 377 | FF |
| 10 | 1010 | 12 | A |
| 5 | 101 | 5 | 5 |
+------+----------+--------+--------+
对于位类型,位操作被视为应当在数字上下文中进行,但在 MySQL 8.0 及更高的版本中,可以直接使用位操作数字或二进制字符串参数
在这种情况下,就至少要位其中一个参数使用 _binary
介绍器,将位类型的数据指定为二进制字符串上下文
mysql> SET @v1 = b'000010101' | b'000101010';
mysql> SET @v2 = _binary b'000010101' | _binary b'000101010';
mysql> SELECT HEX(@v1), HEX(@v2);
+----------+----------+
| HEX(@v1) | HEX(@v2) |
+----------+----------+
| 3F | 003F |
+----------+----------+
在上面这个范例中,两个位操作的显示结果类似,但没有 _binary
的结果是 BIGINT
值,而 _binary
的结果是二进制字符串。由于结果类型不同,显示的值不同:数字结果不显示高位 0
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。