mysql - 如何使用 MySQL 存储和改变位图/位集?

标签 mysql sql bit-manipulation rdbms bitset

我想创建一个存储 500 字节位图 ( 500 bytes * 8 bits per byte = 4000 bits ) 的表列,并执行操作以改变位图中某些索引处的位(设置为 1 或 0)。

然而,documentation page on bitmaps is mostly empty留给我的raw bit functions作为唯一的指南。如何在 MySQL 中创建、计数、读取和变异位图作为列类型?

使用 binlpad您可以将 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/

相关文章:

php - 我如何将 "UserID"与 "username"链接起来,以便我可以更新我的表?

php - sphinx 全文搜索与列过滤

c# - 我应该如何在 C# 中存储 256 位数字并对其执行数学运算?

mysql - MySQL 中名为 Status 的列

java - 在 JPA 查询中,我可以将属性顺序和 DESC/ASC 顺序作为方法签名中的参数传递吗?

MySQL:将多行(带有空值)合并为一行?

c - 这有可能使用某种位魔术来实现吗?

mysql - SQL Dump导入报错原因及解决办法

mysql - 将 varchar 列移动到不同的表并稍后使用联接是否会提高性能?

ruby - 在 Ruby 整数中提取位