下面是官方给出的定义:
位-值类型-位
这个
BIT
数据类型用于存储位值。一种BIT(M)
启用存储M
-位值。M
范围从1到64。若要指定位值,
b'value'
可以使用符号。value
是使用零和1编写的二进制值。例如,b'111'
和b'10000000'
分别代表7和128。如果将值赋值给
BIT(M)
列小于M
位长,该值在左边用零填充。例如,分配一个b'101'
转到BIT(6)
列实际上与分配b'000101'
.NDB集群所有数据的最大组合大小。
BIT
在给定的列中使用的列NDB表不得超过4096位。
注意上面的M的最大值是64.
原本想自己写点东西,结果发现官方文档介绍的挺全的,直接引用吧。
9.1.5位值文字
位值文字是使用
b'val'
或0bval
符号。val
是使用零和1编写的二进制值。任何前导字母b
不重要。领军0b
是区分大小写的,不能写为0B
.法律位值文字:
b'01' B'01' 0b01
非法位值文字:
b'2' (2 is not a binary digit) 0B01 (0B must be written as 0b)
默认情况下,位值文字是二进制字符串:
mysql>
SELECT b'1000001', CHARSET(b'1000001');
+------------+---------------------+ | b'1000001' | CHARSET(b'1000001') | +------------+---------------------+ | A | binary | +------------+---------------------+ mysql>SELECT 0b1100001, CHARSET(0b1100001);
位值文字可能有一个可选的字符集引导者和
COLLATE
子句,将其指定为使用特定字符集和排序规则的字符串:
[_
charset_name
] b'val
' [COLLATEcollation_name
]
例子:
SELECT _latin1 b'1000001'; SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;
示例使用
b'val'
符号,但是0bval
符号也允许介绍。有关介绍人的信息,请参阅第10.3.8节,“字符集介绍人”.在数字上下文中,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;
空位值(
b''
)计算结果为零长度二进制字符串。转换成一个数字,它产生0:
mysql>
SELECT CHARSET(b''), LENGTH(b'');
+--------------+-------------+ | CHARSET(b'') | LENGTH(b'') | +--------------+-------------+ | binary | 0 | +--------------+-------------+ mysql>SELECT b''+0;
位值表示法便于指定要分配给的值。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;
12.12位函数和运算符
表12.16位函数和运算符
名字描述BIT_COUNT()返回设置的位数。&按位和~位反演|按位或^位异或<<左移>>右移
位函数和运算符包括BIT_COUNT(), BIT_AND(), BIT_OR(), BIT_XOR(), &, |, ^, ~, <<,和>>...()BIT_AND(),BIT_OR(),和BIT_XOR()函数是在第12.20.1节,“聚合(按组分类)函数说明”)当前,位函数和运算符需要BIGINT(64位整数)参数和返回BIGINT值,因此它们的最大范围为64位。其他类型的参数转换为BIGINT可能会发生截断。
MySQL 8.0的扩展将此转换为-BIGINT行为:位函数和运算符允许二进制字符串类型参数(BINARY, VARBINARY,以及BLOB),使它们能够接受参数并生成大于64位的返回值。因此,MySQL5.7中对二进制参数的位操作可能会在MySQL8.0中产生不同的结果。为了提前通知这种行为上的潜在变化,服务器将为MySQL8.0中未将二进制参数转换为整数的位操作生成警告(MySQL5.7.11)。这些警告提供了重写受影响语句的机会。要显式地生成mysql 5.7行为,在升级到8.0后不会发生更改,可以使用位操作二进制参数将其转换为整数。
需要注意的五种有问题的表达式类型是:
nonliteral_binary
{ & | ^ }binary
binary
{ & | ^ }nonliteral_binary
nonliteral_binary
{ << >> }anything
~nonliteral_binary
AGGR_BIT_FUNC
(nonliteral_binary
)
这些表达式返回BIGINT在MySQL 5.7中,二进制字符串在8.0中。
注释说明:
{ op1 op2 ... }
适用于给定表达式类型的运算符列表。binary
:任何类型的二进制字符串参数,包括十六进制文本、位文本或NULL
字面上的。nonliteral_binary
:一个参数,它是一个二进制字符串值,而不是十六进制文本、位文本或NULL
字面上的。AGGR_BIT_FUNC
*采用位值参数的聚合函数:BIT_AND(), BIT_OR(), BIT_XOR().服务器为语句中的每个有问题的表达式生成单个警告,而不是为处理的每一行生成警告。假设包含两个问题表达式的语句从表中选择三行。每个语句执行的警告数是两个,而不是六个。下面的示例说明了这一点。
mysql>
CREATE TABLE t(vbin1 VARBINARY(32), vbin2 VARBINARY(32));
Query OK, 0 rows affected (0.03 sec) mysql>INSERT INTO t VALUES (3,1), (3,2), (3,3);
Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql>SELECT HEX(vbin1 & vbin2) AS op1,
->HEX(vbin1 | vbin2) AS op2
->FROM t;
+------+------+ | op1 | op2 | +------+------+ | 1 | 3 | | 2 | 3 | | 3 | 3 | +------+------+ 3 rows in set, 2 warnings (0.00 sec) mysql>SHOW WARNINGS\G
为了避免受影响的语句在升级到MySQL8.0后产生不同的结果,请重写它,使其不生成位操作警告。若要执行此操作,请将至少一个二进制参数强制转换为BIGINT带着CAST(... AS UNSIGNED)...这使得MySQL 5.7隐式二进制到整数转换显式化:
mysql>
SELECT HEX(CAST(vbin1 AS UNSIGNED) & CAST(vbin2 AS UNSIGNED)) AS op1,
->HEX(CAST(vbin1 AS UNSIGNED) | CAST(vbin2 AS UNSIGNED)) AS op2
->FROM t;
+------+------+ | op1 | op2 | +------+------+ | 1 | 3 | | 2 | 3 | | 3 | 3 | +------+------+ 3 rows in set (0.01 sec) mysql>SHOW WARNINGS\G
随着语句的重写如图所示,MySQL8.0尊重将二进制参数视为整数的意图,并产生与5.7中相同的结果。另外,将语句从MySQL 5.7复制到8.0并不会在不同的服务器上产生不同的结果。
无法重写的受影响语句在升级和复制方面会遇到以下潜在问题:
- 在升级到MySQL8.0之后,该语句可能返回不同的结果。
- 从旧版本复制到MySQL8.0可能会导致基于语句和混合格式的二进制日志记录失败。在8.0服务器上重放旧二进制日志也是如此(例如,使用mysqlbinlog)。为了避免这种情况,在旧的主服务器上切换到基于行的二进制日志记录。
下面的列表描述了可用的位函数和运算符:
- |按比特或。
结果是一个无符号64位整数. mysql>SELECT 29 | 15;
- &按位和。
结果是一个无符号64位整数. mysql>SELECT 29 & 15;
- ^按位异或
结果是一个无符号64位整数. mysql>SELECT 1 ^ 1;
-> 0 mysql>SELECT 1 ^ 0;
-> 1 mysql>SELECT 11 ^ 3;
- <<移动一个龙龙(BIGINT)左边的号码。
结果是一个无符号64位整数.该值被截断为64位。特别是,如果移位计数大于或等于无符号64位数的宽度,则结果为零。 mysql>SELECT 1 << 2;
- >>移动一个龙龙(BIGINT)右边的号码。
结果是一个无符号64位整数.该值被截断为64位。特别是,如果移位计数大于或等于无符号64位数的宽度,则结果为零。 mysql>SELECT 4 >> 2;
- ~倒置所有比特。
结果是一个无符号64位整数. mysql>SELECT 5 & ~1;
- BIT_COUNT(
N
)返回在参数中设置的位数。N
为无符号64位整数,或NULL
如果争论是NULL
. mysql>SELECT BIT_COUNT(29), BIT_COUNT(b'101010');