我想创建一个存储 500 字节位图 ( 500 bytes * 8 bits per byte = 4000 bits
) 的表列,并执行操作以改变位图中某些索引处的位(设置为 1 或 0)。
然而,documentation page on bitmaps is mostly empty留给我的raw bit functions作为唯一的指南。如何在 MySQL 中创建、计数、读取和变异位图作为列类型?
使用 bin
和 lpad
您可以将 64 位数字打印为二进制字符串。
LPAD(BIN(34), 64, '0')
0000000000000000000000000000000000000000000000000000000000100010
但是,您如何打印出可能为 4000 位长的二进制/blob/varbinary 字符串?
(注意:不是在谈论位图索引)
最佳答案
首先,升级到 MySQL 8.0。这不适用于早期版本的 MySQL。
您应该使用 BINARY、VARBINARY 或 BLOB,具体取决于要存储的位域的长度。
mysql> create table mytable ( bits binary(500) );
ERROR 1074 (42000): Column length too big for column 'bits' (max = 255); use BLOB or TEXT instead
mysql> create table mytable ( bits blob(500) );
Query OK, 0 rows affected (0.02 sec)
使用 UNHEX() 从十六进制字符串形成位域。直接使用二进制字节太困难了。
mysql> insert into mytable set bits = unhex(repeat('00', 500));
Query OK, 1 row affected (0.00 sec)
您可以使用按位运算符,如
|
, &
, ^
, 和 ~
与位域。但是字符串的长度必须相同!mysql> update mytable set bits = bits | b'01000';
ERROR 3513 (HY000): Binary operands of bitwise operators must be of equal length
这很不方便,但您必须使用 CONCAT() 形成正确长度的字符串:
mysql> update mytable set bits = bits | unhex(concat(repeat('00', 498), 'ffff'));
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
读取一个位串(我为这个显示缩短了它):
mysql> select hex(bits) from mytable\G
*************************** 1. row ***************************
hex(bits): 000...000FFFF
BIT_COUNT() 函数有效:
mysql> select bit_count(bits) from mytable;
+-----------------+
| bit_count(bits) |
+-----------------+
| 16 |
+-----------------+
mysql> select bit_count(~bits) from mytable;
+------------------+
| bit_count(~bits) |
+------------------+
| 3984 |
+------------------+
这时候,您应该坐下来思考 SQL 是否是完成此任务的最佳工具,即使具有 MySQL 8.0 的功能。您会发现在大多数其他编程语言中进行按位运算更加灵活和强大。
关于mysql - 如何使用 MySQL 存储和改变位图/位集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60645538/