Documentation Home
MySQL 8.0 参考手册  / 第 12 章函数和运算符  /  12.13 位函数和运算符

12.13 位函数和运算符

表 12.17 位函数和运算符

姓名 描述
& 按位与
>> 右移
<< 左移
^ 按位异或
BIT_COUNT() 返回设置的位数
| 按位或
~ 按位取反

位函数和运算符包括 BIT_COUNT(), BIT_AND(), BIT_OR(), BIT_XOR(), &, |, ^, ~, <<>>。(BIT_AND()BIT_OR()BIT_XOR()聚合函数在第 12.20.1 节“聚合函数描述”中描述。)在 MySQL 8.0 之前,位函数和运算符需要 BIGINT(64 位整数)参数和返回BIGINT值,因此它们的最大范围是64 位。非参数在执行操作之前 BIGINT被转换为并且可能发生截断。BIGINT

在 MySQL 8.0 中,位函数和运算符允许二进制字符串类型参数(BINARYVARBINARYBLOB类型)并返回类似类型的值,这使它们能够接受参数并产生大于 64 位的返回值。非二进制字符串参数将BIGINT像以前一样转换为并进行处理。

这种行为变化的含义是二进制字符串参数的位操作可能在 MySQL 8.0 中产生与 5.7 中不同的结果。有关如何在 MySQL 5.7 中为 MySQL 5.7 和 8.0 之间的潜在不兼容性做准备的信息,请参阅 MySQL 5.7 参考手册中的 位函数和运算符

MySQL 8.0 之前的位操作

MySQL 8.0 之前的位操作仅处理无符号的 64 位整数参数和结果值(即无符号 BIGINT值)。必要时将其他类型的参数转换 BIGINT为。例子:

  • 此语句对数字文字进行操作,将其视为无符号 64 位整数:

    mysql> SELECT 127 | 128, 128 << 2, BIT_COUNT(15);
    +-----------+----------+---------------+
    | 127 | 128 | 128 << 2 | BIT_COUNT(15) |
    +-----------+----------+---------------+
    |       255 |      512 |             4 |
    +-----------+----------+---------------+
  • 在执行与第一个语句相同的操作并产生相同的结果之前,此语句对字符串参数('127'to 127等)执行数字转换:

    mysql> SELECT '127' | '128', '128' << 2, BIT_COUNT('15');
    +---------------+------------+-----------------+
    | '127' | '128' | '128' << 2 | BIT_COUNT('15') |
    +---------------+------------+-----------------+
    |           255 |        512 |               4 |
    +---------------+------------+-----------------+
  • 此语句使用十六进制文字作为位操作参数。MySQL 默认将十六进制文字视为二进制字符串,但在数字上下文中将它们评估为数字(请参阅 第 9.1.4 节,“十六进制文字”)。在 MySQL 8.0 之前,数字上下文包括位操作。例子:

    mysql> SELECT X'7F' | X'80', X'80' << 2, BIT_COUNT(X'0F');
    +---------------+------------+------------------+
    | X'7F' | X'80' | X'80' << 2 | BIT_COUNT(X'0F') |
    +---------------+------------+------------------+
    |           255 |        512 |                4 |
    +---------------+------------+------------------+

    位运算中位值文字的处理类似于十六进制文字(即作为数字)。

MySQL 8.0 中的位操作

MySQL 8.0 扩展了位操作以直接处理二进制字符串参数(无需转换)并生成二进制字符串结果。(不是整数或二进制字符串的参数仍会像以前一样转换为整数。)此扩展通过以下方式增强了位操作:

  • 可以对超过 64 位的值进行位操作。

  • 对更自然地表示为二进制字符串而不是整数的值执行位运算更容易。

例如,考虑 UUID 值和 IPv6 地址,它们具有如下人类可读的文本格式:

UUID: 6ccd780c-baba-1026-9564-5b8c656024db
IPv6: fe80::219:d1ff:fe91:1a72

对这些格式的文本字符串进行操作很麻烦。另一种方法是将它们转换为不带分隔符的固定长度二进制字符串。每个都产生一个数据类型的值UUID_TO_BIN() ,一个 16 字节(128 位)长的二进制字符串。以下语句对此进行了说明(用于生成可显示的值): INET6_ATON()BINARY(16)HEX()

mysql> SELECT HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db'));
+----------------------------------------------------------+
| HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db')) |
+----------------------------------------------------------+
| 6CCD780CBABA102695645B8C656024DB                         |
+----------------------------------------------------------+
mysql> SELECT HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72'));
+---------------------------------------------+
| HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72')) |
+---------------------------------------------+
| FE800000000000000219D1FFFE911A72            |
+---------------------------------------------+

这些二进制值很容易通过位操作进行操作,以执行诸如从 UUID 值中提取时间戳或提取 IPv6 地址的网络和主机部分等操作。(例如,请参阅本讨论的后面部分。)

算作二进制字符串的参数包括列值、例程参数、局部变量和具有二进制字符串类型的用户定义变量: BINARYVARBINARY或以下 BLOB类型之一。

十六进制文字和位文字呢?回想一下,这些在 MySQL 中默认是二进制字符串,但在数字上下文中是数字。在 MySQL 8.0 中如何处理位操作?MySQL 是否继续在数字上下文中评估它们,就像 MySQL 8.0 之前所做的那样?还是位操作将它们评估为二进制字符串,既然二进制字符串可以本地处理而无需转换?

回答:使用十六进制文字或位文字来指定位操作的参数是很常见的,目的是它们表示数字,因此当所有位参数都是十六进制或位文字时,MySQL 会继续评估数字上下文中的位操作,以实现向后兼容性。_binary如果您需要作为二进制字符串进行评估,那很容易实现:至少对一个文字 使用 引入器。

  • 这些位操作将十六进制文字和位文字评估为整数:

    mysql> SELECT X'40' | X'01', b'11110001' & b'01001111';
    +---------------+---------------------------+
    | X'40' | X'01' | b'11110001' & b'01001111' |
    +---------------+---------------------------+
    |            65 |                        65 |
    +---------------+---------------------------+
  • 由于 _binary引入者,这些位操作将十六进制文字和位文字评估为二进制字符串:

    mysql> SELECT _binary X'40' | X'01', b'11110001' & _binary b'01001111';
    +-----------------------+-----------------------------------+
    | _binary X'40' | X'01' | b'11110001' & _binary b'01001111' |
    +-----------------------+-----------------------------------+
    | A                     | A                                 |
    +-----------------------+-----------------------------------+

虽然两个语句中的位运算产生的结果的数值为 65,但第二个语句在二进制字符串上下文中运行,其中 65 是 ASCII A

在数值评估上下文中,十六进制文字和位文字参数的允许值最多为 64 位,结果也是如此。相比之下,在二进制字符串评估上下文中,允许的参数(和结果)可以超过 64 位:

mysql> SELECT _binary X'4040404040404040' | X'0102030405060708';
+---------------------------------------------------+
| _binary X'4040404040404040' | X'0102030405060708' |
+---------------------------------------------------+
| ABCDEFGH                                          |
+---------------------------------------------------+

有几种方法可以在位操作中引用十六进制文字或位文字以导致二进制字符串评估:

_binary literal
BINARY literal
CAST(literal AS BINARY)

生成十六进制文字或位文字的二进制字符串评估的另一种方法是将它们分配给用户定义的变量,这会导致具有二进制字符串类型的变量:

mysql> SET @v1 = X'40', @v2 = X'01', @v3 = b'11110001', @v4 = b'01001111';
mysql> SELECT @v1 | @v2, @v3 & @v4;
+-----------+-----------+
| @v1 | @v2 | @v3 & @v4 |
+-----------+-----------+
| A         | A         |
+-----------+-----------+

在二进制字符串上下文中,按位运算参数必须具有相同的长度,否则 ER_INVALID_BITWISE_OPERANDS_SIZE 会发生错误:

mysql> SELECT _binary X'40' | X'0001';
ERROR 3513 (HY000): Binary operands of bitwise
operators must be of equal length

为了满足等长要求,用前导零数字填充较短的值,或者,如果较长的值以前导零数字开头并且可以接受较短的结果值,则删除它们:

mysql> SELECT _binary X'0040' | X'0001';
+---------------------------+
| _binary X'0040' | X'0001' |
+---------------------------+
|  A                        |
+---------------------------+
mysql> SELECT _binary X'40' | X'01';
+-----------------------+
| _binary X'40' | X'01' |
+-----------------------+
| A                     |
+-----------------------+

也可以使用 、 、 或 等函数来完成LPAD()填充 RPAD()SUBSTR()剥离 CAST()。在这种情况下,表达式参数不再都是文字, _binary变得不必要了。例子:

mysql> SELECT LPAD(X'40', 2, X'00') | X'0001';
+---------------------------------+
| LPAD(X'40', 2, X'00') | X'0001' |
+---------------------------------+
|  A                              |
+---------------------------------+
mysql> SELECT X'40' | SUBSTR(X'0001', 2, 1);
+-------------------------------+
| X'40' | SUBSTR(X'0001', 2, 1) |
+-------------------------------+
| A                             |
+-------------------------------+

二进制字符串位操作示例

以下示例说明了使用位操作来提取 UUID 值的各个部分,在本例中为时间戳和 IEEE 802 节点号。此技术需要为每个提取的部分设置位掩码。

将文本 UUID 转换为相应的 16 字节二进制值,以便可以在二进制字符串上下文中使用位操作对其进行操作:

mysql> SET @uuid = UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db');
mysql> SELECT HEX(@uuid);
+----------------------------------+
| HEX(@uuid)                       |
+----------------------------------+
| 6CCD780CBABA102695645B8C656024DB |
+----------------------------------+

为值的时间戳和节点号部分构造位掩码。时间戳包括前三部分(64 位,第 0 到 63 位),节点号是最后一部分(48 位,第 80 到 127 位):

mysql> SET @ts_mask = CAST(X'FFFFFFFFFFFFFFFF' AS BINARY(16));
mysql> SET @node_mask = CAST(X'FFFFFFFFFFFF' AS BINARY(16)) >> 80;
mysql> SELECT HEX(@ts_mask);
+----------------------------------+
| HEX(@ts_mask)                    |
+----------------------------------+
| FFFFFFFFFFFFFFFF0000000000000000 |
+----------------------------------+
mysql> SELECT HEX(@node_mask);
+----------------------------------+
| HEX(@node_mask)                  |
+----------------------------------+
| 00000000000000000000FFFFFFFFFFFF |
+----------------------------------+

此处使用该CAST(... AS BINARY(16))函数是因为掩码的长度必须与应用它们的 UUID 值的长度相同。可以使用其他函数将掩码填充到所需长度来产生相同的结果:

SET @ts_mask= RPAD(X'FFFFFFFFFFFFFFFF' , 16, X'00');
SET @node_mask = LPAD(X'FFFFFFFFFFFF', 16, X'00') ;

使用掩码提取时间戳和节点号部分:

mysql> SELECT HEX(@uuid & @ts_mask) AS 'timestamp part';
+----------------------------------+
| timestamp part                   |
+----------------------------------+
| 6CCD780CBABA10260000000000000000 |
+----------------------------------+
mysql> SELECT HEX(@uuid & @node_mask) AS 'node part';
+----------------------------------+
| node part                        |
+----------------------------------+
| 000000000000000000005B8C656024DB |
+----------------------------------+

前面的示例使用这些位操作:右移 ( >>) 和按位与 ( &)。

笔记

UUID_TO_BIN()采用一个标志,该标志会导致生成的二进制 UUID 值中发生一些位重排。如果您使用该标志,请相应地修改提取掩码。

下一个示例使用位运算来提取 IPv6 地址的网络和主机部分。假设网络部分的长度为 80 位。那么主机部分的长度为 128 − 80 = 48 位。要提取地址的网络和主机部分,将其转换为二进制字符串,然后在二进制字符串上下文中使用位操作。

将文本 IPv6 地址转换为相应的二进制字符串:

mysql> SET @ip = INET6_ATON('fe80::219:d1ff:fe91:1a72');

以位为单位定义网络长度:

mysql> SET @net_len = 80;

通过向左或向右移动全一地址来构造网络和主机掩码。为此,从 address 开始 ::,它是所有零的简写,正如您将其转换为二进制字符串所看到的那样:

mysql> SELECT HEX(INET6_ATON('::')) AS 'all zeros';
+----------------------------------+
| all zeros                        |
+----------------------------------+
| 00000000000000000000000000000000 |
+----------------------------------+

要产生互补值(全一),请使用 ~ 运算符反转位:

mysql> SELECT HEX(~INET6_ATON('::')) AS 'all ones';
+----------------------------------+
| all ones                         |
+----------------------------------+
| FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
+----------------------------------+

向左或向右移动全一值以生成网络和主机掩码:

mysql> SET @net_mask = ~INET6_ATON('::') << (128 - @net_len);
mysql> SET @host_mask = ~INET6_ATON('::') >> @net_len;

显示掩码以验证它们是否覆盖了地址的正确部分:

mysql> SELECT INET6_NTOA(@net_mask) AS 'network mask';
+----------------------------+
| network mask               |
+----------------------------+
| ffff:ffff:ffff:ffff:ffff:: |
+----------------------------+
mysql> SELECT INET6_NTOA(@host_mask) AS 'host mask';
+------------------------+
| host mask              |
+------------------------+
| ::ffff:255.255.255.255 |
+------------------------+

提取并显示地址的网络和主机部分:

mysql> SET @net_part = @ip & @net_mask;
mysql> SET @host_part = @ip & @host_mask;
mysql> SELECT INET6_NTOA(@net_part) AS 'network part';
+-----------------+
| network part    |
+-----------------+
| fe80::219:0:0:0 |
+-----------------+
mysql> SELECT INET6_NTOA(@host_part) AS 'host part';
+------------------+
| host part        |
+------------------+
| ::d1ff:fe91:1a72 |
+------------------+

前面的示例使用这些位操作:补码 ( ~)、左移 ( <<) 和按位与 ( &)。

其余讨论提供了有关每组位操作的参数处理的详细信息、有关位操作中文字值处理的更多信息,以及 MySQL 8.0 和旧版 MySQL 之间的潜在不兼容性。

按位与、或和异或运算

对于&|^位运算,结果类型取决于参数是被计算为二进制字符串还是数字:

  • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或NULL 文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

  • 二进制字符串评估生成与参数长度相同的二进制字符串。如果参数长度不等, ER_INVALID_BITWISE_OPERANDS_SIZE 则会发生错误。数值计算产生一个无符号的 64 位整数。

数值评估的例子:

mysql> SELECT 64 | 1, X'40' | X'01';
+--------+---------------+
| 64 | 1 | X'40' | X'01' |
+--------+---------------+
|     65 |            65 |
+--------+---------------+

二进制字符串评估的示例:

mysql> SELECT _binary X'40' | X'01';
+-----------------------+
| _binary X'40' | X'01' |
+-----------------------+
| A                     |
+-----------------------+
mysql> SET @var1 = X'40', @var2 = X'01';
mysql> SELECT @var1 | @var2;
+---------------+
| @var1 | @var2 |
+---------------+
| A             |
+---------------+

按位补码和移位操作

对于~<<>> 位运算,结果类型取决于位参数是作为二进制字符串还是数字求值:

  • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或NULL文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

  • 二进制字符串评估生成与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

对于移位操作,无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

数值评估的例子:

mysql> SELECT ~0, 64 << 2, X'40' << 2;
+----------------------+---------+------------+
| ~0                   | 64 << 2 | X'40' << 2 |
+----------------------+---------+------------+
| 18446744073709551615 |     256 |        256 |
+----------------------+---------+------------+

二进制字符串评估的示例:

mysql> SELECT HEX(_binary X'1111000022220000' >> 16);
+----------------------------------------+
| HEX(_binary X'1111000022220000' >> 16) |
+----------------------------------------+
| 0000111100002222                       |
+----------------------------------------+
mysql> SELECT HEX(_binary X'1111000022220000' << 16);
+----------------------------------------+
| HEX(_binary X'1111000022220000' << 16) |
+----------------------------------------+
| 0000222200000000                       |
+----------------------------------------+
mysql> SET @var1 = X'F0F0F0F0';
mysql> SELECT HEX(~@var1);
+-------------+
| HEX(~@var1) |
+-------------+
| 0F0F0F0F    |
+-------------+

BIT_COUNT() 操作

BIT_COUNT()函数总是返回一个无符号的 64 位整数,或者NULL 如果参数是NULL.

mysql> SELECT BIT_COUNT(127);
+----------------+
| BIT_COUNT(127) |
+----------------+
|              7 |
+----------------+
mysql> SELECT BIT_COUNT(b'010101'), BIT_COUNT(_binary b'010101');
+----------------------+------------------------------+
| BIT_COUNT(b'010101') | BIT_COUNT(_binary b'010101') |
+----------------------+------------------------------+
|                    3 |                            3 |
+----------------------+------------------------------+

BIT_AND()、BIT_OR() 和 BIT_XOR() 运算

对于BIT_AND()BIT_OR()BIT_XOR()bit 函数,结果类型取决于函数参数值是被计算为二进制字符串还是数字:

  • 当参数值具有二进制字符串类型并且参数不是十六进制文字、位文字或NULL 文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数值转换为无符号 64 位整数。

  • 二进制字符串评估生成与参数值长度相同的二进制字符串。如果参数值的长度不相等, ER_INVALID_BITWISE_OPERANDS_SIZE 则会发生错误。如果参数大小超过 511 字节, ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE 则会发生错误。数值计算产生一个无符号的 64 位整数。

NULL除非所有值都是 ,否则值不会影响结果NULL。在这种情况下,结果是一个中性值,其长度与参数值的长度相同(所有位 1 代表 BIT_AND(),所有位 0 代表 BIT_OR(), 和 BIT_XOR())。

例子:

mysql> CREATE TABLE t (group_id INT, a VARBINARY(6));
mysql> INSERT INTO t VALUES (1, NULL);
mysql> INSERT INTO t VALUES (1, NULL);
mysql> INSERT INTO t VALUES (2, NULL);
mysql> INSERT INTO t VALUES (2, X'1234');
mysql> INSERT INTO t VALUES (2, X'FF34');
mysql> SELECT HEX(BIT_AND(a)), HEX(BIT_OR(a)), HEX(BIT_XOR(a))
       FROM t GROUP BY group_id;
+-----------------+----------------+-----------------+
| HEX(BIT_AND(a)) | HEX(BIT_OR(a)) | HEX(BIT_XOR(a)) |
+-----------------+----------------+-----------------+
| FFFFFFFFFFFF    | 000000000000   | 000000000000    |
| 1234            | FF34           | ED00            |
+-----------------+----------------+-----------------+

十六进制文字、位文字和 NULL 文字的特殊处理

为了向后兼容,当所有位参数都是十六进制文字、位文字或NULL文字时,MySQL 8.0 在数字上下文中评估位操作。也就是说,如果所有位参数都是未修饰的十六进制文字、位文字或文字,则二进制字符串位参数的位操作不使用二进制字符串求值NULL 。(这不适用于此类文字,如果它们是使用_binary介绍 BINARY符、运算符或其他将它们明确指定为二进制字符串的方式编写的。)

刚刚描述的文字处理与 MySQL 8.0 之前的相同。例子:

  • 这些位操作评估数字上下文中的文字并产生BIGINT结果:

    b'0001' | b'0010'
    X'0008' << 8
  • 这些位操作NULL在数字上下文中进行评估并产生BIGINT 具有NULL值的结果:

    NULL & NULL
    NULL >> 4

在 MySQL 8.0 中,您可以通过明确指示至少一个参数是二进制字符串来使这些操作在二进制字符串上下文中评估参数:

_binary b'0001' | b'0010'
_binary X'0008' << 8
BINARY NULL & NULL
BINARY NULL >> 4

最后两个表达式的结果是 NULL,和没有 BINARY运算符一样,但是结果的数据类型是二进制字符串类型,而不是整数类型。

与 MySQL 5.7 的位操作不兼容

因为位操作可以在 MySQL 8.0 中本地处理二进制字符串参数,所以一些表达式在 MySQL 8.0 中产生的结果与 5.7 中不同。需要注意的五种有问题的表达类型是:

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 5.7 中为 MySQL 5.7 和 8.0 之间的潜在不兼容性做准备的信息,请参阅 MySQL 5.7 参考手册中的 位函数和运算符

以下列表描述了可用的位函数和运算符:

  • |

    按位或。

    结果类型取决于参数是被评估为二进制字符串还是数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或 NULL文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与参数长度相同的二进制字符串。如果参数长度不等, ER_INVALID_BITWISE_OPERANDS_SIZE 则会发生错误。数值计算产生一个无符号的 64 位整数。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 29 | 15;
            -> 31
    mysql> SELECT _binary X'40404040' | X'01020304';
            -> 'ABCD'

    如果从 mysql客户端中调用按位或,则二进制字符串结果使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • &

    按位与。

    结果类型取决于参数是被评估为二进制字符串还是数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或 NULL文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与参数长度相同的二进制字符串。如果参数长度不等, ER_INVALID_BITWISE_OPERANDS_SIZE 则会发生错误。数值计算产生一个无符号的 64 位整数。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 29 & 15;
            -> 13
    mysql> SELECT HEX(_binary X'FF' & b'11110000');
            -> 'F0'

    如果从 mysql客户端中调用按位与,则二进制字符串结果使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • ^

    按位异或。

    结果类型取决于参数是被评估为二进制字符串还是数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或 NULL文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与参数长度相同的二进制字符串。如果参数长度不等, ER_INVALID_BITWISE_OPERANDS_SIZE 则会发生错误。数值计算产生一个无符号的 64 位整数。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 1 ^ 1;
            -> 0
    mysql> SELECT 1 ^ 0;
            -> 1
    mysql> SELECT 11 ^ 3;
            -> 8
    mysql> SELECT HEX(_binary X'FEDC' ^ X'1111');
            -> 'EFCD'

    如果从 mysql客户端中调用按位异或,则二进制字符串结果使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • <<

    将 longlong ( BIGINT) 数字或二进制字符串向左移动。

    结果类型取决于位参数是作为二进制字符串还是数字计算:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或NULL 文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

    无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 1 << 2;
            -> 4
    mysql> SELECT HEX(_binary X'00FF00FF00FF' << 8);
            -> 'FF00FF00FF00'

    如果从 mysql客户端中调用位移位,二进制字符串结果将使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • >>

    将 longlong ( BIGINT) 数字或二进制字符串右移。

    结果类型取决于位参数是作为二进制字符串还是数字计算:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或NULL 文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

    无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 4 >> 2;
            -> 1
    mysql> SELECT HEX(_binary X'00FF00FF00FF' >> 8);
            -> '0000FF00FF00'

    如果从 mysql客户端中调用位移位,二进制字符串结果将使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • ~

    反转所有位。

    结果类型取决于位参数是作为二进制字符串还是数字计算:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或NULL 文字时,会发生二进制字符串评估。否则会进行数字评估,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串评估生成与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

    有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 5 & ~1;
            -> 4
    mysql> SELECT HEX(~X'0000FFFF1111EEEE');
            -> 'FFFF0000EEEE1111'

    如果从 mysql客户端中调用按位反转,二进制字符串结果将使用十六进制表示法显示,具体取决于--binary-as-hex. 有关该选项的更多信息,请参阅 第 4.5.1 节,“mysql — MySQL 命令行客户端”

  • BIT_COUNT(N)

    返回在参数中设置 N为无符号 64 位整数的位数,或者NULL如果参数是 NULL.

    mysql> SELECT BIT_COUNT(64), BIT_COUNT(BINARY 64);
            -> 1, 7
    mysql> SELECT BIT_COUNT('64'), BIT_COUNT(_binary '64');
            -> 1, 7
    mysql> SELECT BIT_COUNT(X'40'), BIT_COUNT(_binary X'40');
            -> 1, 1